M是一个整数2D矩阵(nXm),它们按行和列进行排序。编写一个函数search(int s),返回数字的确切位置或Null。最有效的方法是什么?
M是一个整数2D矩阵(nXm),它们按行和列进行排序。编写一个函数search(int s),返回数字的确切位置或Null。最有效的方法是什么?
初始化: m[1..n(行),1....m(列)]
i=n,j=1
从(i,j)开始:
STEP 1) if the value equals m(i,j) return (i,j)
STEP 2) if the value > m(i,j) go to step 1 with j+=1
STEP 3) else go to step 1 with i-=1
在每一步中,如果 j 或 i 超出范围,则返回无解。
这个解决方案的复杂度是 O(n+m),如果 n=m,则复杂度为 O(n)。
我想知道是否有像二分查找那样的 log(n*m) 解决方案。
编辑 另一个可能的解决方案:
STEP 1)take the middle (n/2,m/2) of the matrix and compare it to the value
STEP 2) if the value equals m(i,j) return (i,j)
STEP 3) if the value is higher you can get rid from the first quarter
STEP 4) if the value is lower you can get rid from the forth quarter
STEP 5) split the 3 other quarters to 2, a rectangle and a box,
send those both items to step 1 in a recursive manner
我不确定这种解决方案的效率: 如果 R = N*M,则 T(R) = T(R/2) + T(R/4) + O(1)
(如果R等于N乘以M,那么T(R)等于T(R/2)加上T(R/4)再加上O(1))O(R^(log_{4}(3))) = O(R^0.8)
),但是无法想出O(n+m)的算法。当我最终放弃时,他说“走相反的对角线”,我立刻恍然大悟! - BlueRaja - Danny Pflughoeft假设我们有以下代码:
1 2 5 7
2 4 7 9
3 5 8 9
5 6 9 9
1 2 5*7
2 4*7 9
3 5*8 9
5*6*9 9
所以一个算法会是:
int[] SearchArray(int s, int[][] array)
{
int i = 0;
int j = 0;
int n = array.GetLength(0);
int m = array.GetLength(1);
if (s > array[n][m])
return null;
while (i < n && j < m)
{
if (array[i][j] > s)
return null;
if (array[i][j] == s)
return new int[]{i,j};
try
{
if (array[i+1][j+1] < s)
{
i++;
j++;
}
else if (array[i+1][j] > array[i][j+1])
if (array[i+1][j] < s)
i++;
else
j++;
else if (array[i][j+1] > array[i+1][j])
if (array[i][j+1] < s)
j++;
else
i++;
else if (array[i+1][j] == array[i][j+1])
if (n < m)
i++;
else
j++;
}
catch(IndexOutOfRangeException e)
{
if (i == n-1)
j++;
if (k == m-1)
i++;
}
}
}
为了优化和格式化而编辑