老鼠和毒酒问题:1000瓶酒其中1瓶有毒,用10只老鼠找出毒酒。
解题方法1:折半查找法。取500瓶内各一滴,看老鼠是否死亡,以此排除一半的酒。
解题方法2:转换为二进制法。1-1000都可以用10位2进制数表示,设x10 = 10010111012,则将第x瓶酒滴入二进制位为1的位对应的碗中,然后让10只老鼠各喝一个碗中的酒,可得到毒酒对应的二进制。子数组最大和问题:输入一个整数数组,数组里有正数也有负数。数组中连续的一个或多个整数组成一个子数组,求子数组和的最大值。要求时间复杂度为O(n)。
解法:动态规划。
设dp[i]表示以第i个数结束的子数组的最大和,那么dp[i+1] = max(dp[i] + nums[i+1], nums[i+1])。子数组和的最大值为dp数组中的最大值。买饮料问题:三个瓶盖可以换一瓶饮料,要喝100瓶饮料,最少需要买多少瓶?
解法:2瓶饮料+1个瓶盖 = 3瓶饮料+1个瓶盖。因此需要买2 x (100/3) + 1 = 67瓶。最后一瓶正好作为启动。生成数组(不能用除法):给你一个数组A[1..n],请你在O(n)的时间里构造一个新的数组B[1..n],使得B[i]=A[1] x A[2] x … x A[n] / A[i]。你不能使用除法运算。
解题方法:改造辅助数组。任意B[i] = A[1] x A[2] x ... x A[i-1] x A[i+1] x ... x A[n]。构造辅助数组C[1..n-1], D[1..n-1],其中C[i] = A[1] x A[2] x ... x A[i],D[i] = A[i] x ... x A[n]。构造C、D数组都是O(n)复杂度,最后由C、D数组得到B数组也是O(n)复杂度。互信息的计算:I(A, B) = log2P(AB)/(P(A)P(B)) = log2p(A|B)/P(A) = log2P(B|A)/P(B)
算法设计题:已知计算机有以下原子操作:1). 赋值操作:b = a; 2). ++a和a+1; 3). for( ){ ***}有限循环; 4). 操作数只能为0或者正整数; 5). 定义函数实现加减乘操作。要求实现加减乘除操作。
解题hint:首先想办法实现-1的功能。
fun_dec(n){
a = 0
b = 0
for(n times){
b = a
++a
}
return b
}
有了-1功能即可实现减法,有了加法减法即可实现乘法除法。
【数据结构类】实现一个对链表排序的算法,C/C++可以使用std::list<int>,Java使用LinkedList<integer>要求先描述算法,然后再实现,算法效率尽可能高效。
解题hint:递归进行归并排序。使用快慢指针可以快速找到链表的中间位置(满指针走一步,快指针走两步,块指针到达链表末尾则慢指针到达链表中间位置)。匈牙利法求最优任务分配。
走两趟格子:有n*n个格子,每个格子里有正数或者0,从最左上角往最右下角走,只能向下和向右,一共走两次(即从左上角走到右下角走两趟),把所有经过的格子的数加起来,求最大值SUM,且两次如果经过同一个格子,则最后总和SUM中该格子的计数只加一次。
解题报告:一篇博文
需要DP两次走的状态。
状态转移:
if(i != j)
DP[s, i ,j] = Max(DP[s - 1, i - 1, j - 1], DP[s - 1, i - 1, j], DP[s - 1, i, j - 1], DP[s - 1, i, j]) + W[s,i] + W[s,j]
else
DP[s, i ,j] = Max(DP[s - 1, i - 1, j - 1], DP[s - 1, i - 1, j], DP[s - 1, i, j]) + W[s,i]
N个整数(数的大小为0-255)的序列,把它们加密为K个整数(数的大小为0-255).再将K个整数顺序随机打乱,使得可以从这乱序的K个整数中解码出原序列。设计加密解密算法,且要求K<=15N.如果是:
1). N<=16,要求K<=16N.
2). N<=16,要求K<=10N.
3). N<=64,要求K<=15N.
我表示连题都看不懂,看了网上答案发现主要是对第i个数字第k位是什么进行编码。一个字符串中含有n个字符,其中有m个不同的字符,n>>m,用最少的时间和空间找到包含所有这m个字符的最短的字串,不考虑特殊字符,只考虑字母数字即可。
例如:abccbaddac, 返回:cbad
aabcadbbbcca,返回:bcad
解题方法:设不同的字母共有m个,首先从左往右找到第一个包含所有字母的子串,长度为L,然后从L-m处开始重新寻找。取找到的最短长度即可。