4-2:
题目描述:
某数组A[1,2,...n]含有所有从0到n的证书,但其中一个整数不在数组中。通过辅助数组B[0,...n]来记录A中出现的整数
(1)在O(n)时间找到缺失整数
(2)若数组中每个数值是二进制的,不能直接对每个数取出其数值,则如何找到缺失
解答:
(1)遍历数组A,将每个出现的值存储在B中下标对应值,之后遍历一次B即可
eg:
for val in A:
B[val] = 1
for i in range(len(B)):
if B[i] == 0:
return i
(2)使用异或操作来处理。1^0 = 0,1^1 = 0,0^0 = 0,既:两个相等的数异或结果为0,而0与任何数异或得该数本身。因此,将A中的值与0~n异或,得到的结果就是缺失的整数。
6-3:
题目描述:Young 氏矩阵:从左到右递增,从上到下递增。
(1)插入一个新元素的算法及复杂度
(2)对n*n个数使用young氏矩阵排序的复杂度为O(n^3)
(3)在m*n矩阵中找到一个给定数,复杂度O(m + n)
解答:
(1)在矩阵右下角插入新元素。若新元素大于上方与前方的元素,则插入成功。否则, 将新元素往小的方向比较交换过去。最坏情况的复杂度为:走到了左上角O(n+m)
void insert(vec,i,j)
{
//此处仅提供参考思想,不具体涉及边缘控制
curr = vec[i][j];
left = vec[i][j-1];
up = vec[i-1][j];
if(curr >= left && curr >= up)
return; //找到合适位置
else if(curr < left)
insert(v,i,j-1)
else
insert(v,i-1,j)
}
(2)对 n * n 个元素使用Young矩阵,每个元素插入该矩阵的复杂度是O(n+n),则,总的复杂度为O(2n*n*n) = O(n^3)。对一个Y矩阵,左上角为最小值,最左一列递增,最顶一行递增,则使用合并排序中的摸牌式合并方法,O(m+n)的复杂度就可以排序好第一列与第一行。同样的方法。遍历整个矩阵一次,就可以完成排序
(3) 从左下角起寻找元素。若当前值小于需要值,则往右;若当前值大于需要值,则往上。复杂度为O(m + n)