【发布时间】:2014-07-15 13:42:07
【问题描述】:
我一直在寻找对排序矩阵使用二分搜索逻辑的最佳优化方式。
使用 Stack Over flow 中“Michal Sznajder”建议的逻辑。 Most efficient way to search a sorted matrix?
但是具有递归关系的计算时间复杂度有困难。 谁能帮帮我。
虽然我使用的是二分搜索逻辑,但我认为它不是 T(n) = log (m + n)。
是 T(n) = log (log ( log (m x n))) 还是 log ( log (m x n)) ?
代码可能不是最好的标准或优化,但我刚开始写。
/*
1, 4, 7, 10, 13,
2, 5, 8, 11, 14,
3, 6, 9, 12, 15,
16, 17, 18, 19, 20,
21, 22, 23, 24, 25,
26, 27, 28, 29, 30
a ..... b ..... c
. . . . .
. 1 . 2 .
. . . . .
d ..... e ..... f
. . . . .
. 3 . 4 .
. . . . .
g ..... h ..... i
a, c, g < i --> if not there is no element
a, b, d < e
b, c, e < f
d, e, g < h
e, f, h < i
Left Top : Right Top
-----------Mid--------------
Left Bottom : Right Bottom
*/
public int SearchSortedMatrixInLogNByM(int[,] SortedMatix, int elementToSearch, int rowStPos, int colStPos, int rowEndPos, int colEndPos)
{
// Step 0. Check for basic validations.
if (SortedMatix == null)
{
throw new Exception("Matrix is empty");
}
// Step 1. Use divide and conquer and to get the middle element.
int resultNode = 0;
int rowMidPos = (rowStPos + rowEndPos) / 2;
int colMidPos = (colStPos + colEndPos) / 2;
// Step 2. Mid element in Recursive Sub Matrix. For e.g in above example if it is 'e', 'f','h','i' then found.
if (SortedMatix[rowMidPos, colMidPos] == elementToSearch || SortedMatix[rowMidPos, colEndPos] == elementToSearch ||
SortedMatix[rowEndPos, colMidPos] == elementToSearch || SortedMatix[rowEndPos, colEndPos] == elementToSearch)
{
return elementToSearch;
}
// Step 3. Terminate the sub matrix iteration when the element is not found in the 2 X 2 matrix.
if ((rowStPos == rowMidPos || colStPos == colMidPos) && SortedMatix[rowStPos, colStPos] != elementToSearch)
{
return 0;
}
// Step 4. Left Top Sub Matrix.
if (resultNode == 0 && elementToSearch < SortedMatix[rowMidPos, colMidPos])
{
resultNode = SearchSortedMatrixInLogNByM(SortedMatix, elementToSearch, rowStPos, colStPos, rowMidPos, colMidPos);
}
// Step 5. Right Top Sub Matrix.
if (resultNode == 0 && elementToSearch < SortedMatix[rowMidPos, colEndPos])
{
resultNode = SearchSortedMatrixInLogNByM(SortedMatix, elementToSearch, rowStPos, colMidPos, rowMidPos, colEndPos);
}
// Step 6. Left bottom Sub Matrix.
if (resultNode == 0 && elementToSearch < SortedMatix[rowEndPos, colMidPos])
{
resultNode = SearchSortedMatrixInLogNByM(SortedMatix, elementToSearch, rowMidPos, colStPos, rowEndPos, colMidPos);
}
// Step 7. Right bottom Sub Matrix.
if (resultNode == 0 && elementToSearch < SortedMatix[rowEndPos, colEndPos])
{
resultNode = SearchSortedMatrixInLogNByM(SortedMatix, elementToSearch, rowMidPos, colMidPos, rowEndPos, colEndPos);
}
return resultNode;
}
public void SearchSortedMatrixTest()
{
int[,] SortedMatix = {{ 1, 4, 7, 10, 13,},
{ 2, 5, 8, 11, 14,},
{ 3, 6, 9, 12, 15,},
{ 16, 17, 18, 19, 20,},
{ 21, 22, 23, 24, 25,},
{ 26, 27, 28, 29, 30}};
//SearchSortedMatrixInNLogN(AssendMatix, 21);
StringBuilder strBldr = new StringBuilder();
strBldr.Append("\n 1 : " + SearchSortedMatrixInLogNByM(SortedMatix, 1, 0, 0, SortedMatix.GetLength(0) - 1, SortedMatix.GetLength(1) - 1));
strBldr.Append("\n 2 : " + SearchSortedMatrixInLogNByM(SortedMatix, 2, 0, 0, SortedMatix.GetLength(0) - 1, SortedMatix.GetLength(1) - 1));
strBldr.Append("\n 3 : " + SearchSortedMatrixInLogNByM(SortedMatix, 3, 0, 0, SortedMatix.GetLength(0) - 1, SortedMatix.GetLength(1) - 1));
strBldr.Append("\n 4 : " + SearchSortedMatrixInLogNByM(SortedMatix, 4, 0, 0, SortedMatix.GetLength(0) - 1, SortedMatix.GetLength(1) - 1));
strBldr.Append("\n 5 : " + SearchSortedMatrixInLogNByM(SortedMatix, 5, 0, 0, SortedMatix.GetLength(0) - 1, SortedMatix.GetLength(1) - 1));
strBldr.Append("\n 6 : " + SearchSortedMatrixInLogNByM(SortedMatix, 6, 0, 0, SortedMatix.GetLength(0) - 1, SortedMatix.GetLength(1) - 1));
strBldr.Append("\n 7 : " + SearchSortedMatrixInLogNByM(SortedMatix, 7, 0, 0, SortedMatix.GetLength(0) - 1, SortedMatix.GetLength(1) - 1));
strBldr.Append("\n 8 : " + SearchSortedMatrixInLogNByM(SortedMatix, 8, 0, 0, SortedMatix.GetLength(0) - 1, SortedMatix.GetLength(1) - 1));
strBldr.Append("\n 9 : " + SearchSortedMatrixInLogNByM(SortedMatix, 9, 0, 0, SortedMatix.GetLength(0) - 1, SortedMatix.GetLength(1) - 1));
strBldr.Append("\n 10 : " + SearchSortedMatrixInLogNByM(SortedMatix, 10, 0, 0, SortedMatix.GetLength(0) - 1, SortedMatix.GetLength(1) - 1));
strBldr.Append("\n 11 : " + SearchSortedMatrixInLogNByM(SortedMatix, 11, 0, 0, SortedMatix.GetLength(0) - 1, SortedMatix.GetLength(1) - 1));
strBldr.Append("\n 12 : " + SearchSortedMatrixInLogNByM(SortedMatix, 12, 0, 0, SortedMatix.GetLength(0) - 1, SortedMatix.GetLength(1) - 1));
strBldr.Append("\n 13 : " + SearchSortedMatrixInLogNByM(SortedMatix, 13, 0, 0, SortedMatix.GetLength(0) - 1, SortedMatix.GetLength(1) - 1));
strBldr.Append("\n 14 : " + SearchSortedMatrixInLogNByM(SortedMatix, 14, 0, 0, SortedMatix.GetLength(0) - 1, SortedMatix.GetLength(1) - 1));
strBldr.Append("\n 15 : " + SearchSortedMatrixInLogNByM(SortedMatix, 15, 0, 0, SortedMatix.GetLength(0) - 1, SortedMatix.GetLength(1) - 1));
strBldr.Append("\n 16 : " + SearchSortedMatrixInLogNByM(SortedMatix, 16, 0, 0, SortedMatix.GetLength(0) - 1, SortedMatix.GetLength(1) - 1));
strBldr.Append("\n 17 : " + SearchSortedMatrixInLogNByM(SortedMatix, 17, 0, 0, SortedMatix.GetLength(0) - 1, SortedMatix.GetLength(1) - 1));
strBldr.Append("\n 18 : " + SearchSortedMatrixInLogNByM(SortedMatix, 18, 0, 0, SortedMatix.GetLength(0) - 1, SortedMatix.GetLength(1) - 1));
strBldr.Append("\n 19 : " + SearchSortedMatrixInLogNByM(SortedMatix, 19, 0, 0, SortedMatix.GetLength(0) - 1, SortedMatix.GetLength(1) - 1));
strBldr.Append("\n 20 : " + SearchSortedMatrixInLogNByM(SortedMatix, 20, 0, 0, SortedMatix.GetLength(0) - 1, SortedMatix.GetLength(1) - 1));
strBldr.Append("\n 21 : " + SearchSortedMatrixInLogNByM(SortedMatix, 21, 0, 0, SortedMatix.GetLength(0) - 1, SortedMatix.GetLength(1) - 1));
strBldr.Append("\n 22 : " + SearchSortedMatrixInLogNByM(SortedMatix, 22, 0, 0, SortedMatix.GetLength(0) - 1, SortedMatix.GetLength(1) - 1));
strBldr.Append("\n 23 : " + SearchSortedMatrixInLogNByM(SortedMatix, 23, 0, 0, SortedMatix.GetLength(0) - 1, SortedMatix.GetLength(1) - 1));
strBldr.Append("\n 24 : " + SearchSortedMatrixInLogNByM(SortedMatix, 24, 0, 0, SortedMatix.GetLength(0) - 1, SortedMatix.GetLength(1) - 1));
strBldr.Append("\n 25 : " + SearchSortedMatrixInLogNByM(SortedMatix, 25, 0, 0, SortedMatix.GetLength(0) - 1, SortedMatix.GetLength(1) - 1));
strBldr.Append("\n 26 : " + SearchSortedMatrixInLogNByM(SortedMatix, 26, 0, 0, SortedMatix.GetLength(0) - 1, SortedMatix.GetLength(1) - 1));
strBldr.Append("\n 27 : " + SearchSortedMatrixInLogNByM(SortedMatix, 27, 0, 0, SortedMatix.GetLength(0) - 1, SortedMatix.GetLength(1) - 1));
strBldr.Append("\n 28 : " + SearchSortedMatrixInLogNByM(SortedMatix, 28, 0, 0, SortedMatix.GetLength(0) - 1, SortedMatix.GetLength(1) - 1));
strBldr.Append("\n 29 : " + SearchSortedMatrixInLogNByM(SortedMatix, 29, 0, 0, SortedMatix.GetLength(0) - 1, SortedMatix.GetLength(1) - 1));
strBldr.Append("\n 30 : " + SearchSortedMatrixInLogNByM(SortedMatix, 30, 0, 0, SortedMatix.GetLength(0) - 1, SortedMatix.GetLength(1) - 1));
strBldr.Append("\n\n Example 2:\n");
SortedMatix = new int[,] {{ 1, 4, 7,},
{ 2, 5, 8,},
{ 3, 6, 9}};
strBldr.Append("\n 1 : " + SearchSortedMatrixInLogNByM(SortedMatix, 1, 0, 0, SortedMatix.GetLength(0) - 1, SortedMatix.GetLength(1) - 1));
strBldr.Append("\n 2 : " + SearchSortedMatrixInLogNByM(SortedMatix, 2, 0, 0, SortedMatix.GetLength(0) - 1, SortedMatix.GetLength(1) - 1));
strBldr.Append("\n 3 : " + SearchSortedMatrixInLogNByM(SortedMatix, 3, 0, 0, SortedMatix.GetLength(0) - 1, SortedMatix.GetLength(1) - 1));
strBldr.Append("\n 4 : " + SearchSortedMatrixInLogNByM(SortedMatix, 4, 0, 0, SortedMatix.GetLength(0) - 1, SortedMatix.GetLength(1) - 1));
strBldr.Append("\n 5 : " + SearchSortedMatrixInLogNByM(SortedMatix, 5, 0, 0, SortedMatix.GetLength(0) - 1, SortedMatix.GetLength(1) - 1));
strBldr.Append("\n 6 : " + SearchSortedMatrixInLogNByM(SortedMatix, 6, 0, 0, SortedMatix.GetLength(0) - 1, SortedMatix.GetLength(1) - 1));
strBldr.Append("\n 7 : " + SearchSortedMatrixInLogNByM(SortedMatix, 7, 0, 0, SortedMatix.GetLength(0) - 1, SortedMatix.GetLength(1) - 1));
strBldr.Append("\n 8 : " + SearchSortedMatrixInLogNByM(SortedMatix, 8, 0, 0, SortedMatix.GetLength(0) - 1, SortedMatix.GetLength(1) - 1));
strBldr.Append("\n 9 : " + SearchSortedMatrixInLogNByM(SortedMatix, 9, 0, 0, SortedMatix.GetLength(0) - 1, SortedMatix.GetLength(1) - 1));
MessageBox.Show("Element(s) Search in Sorted Matrix and the result(s) are " + strBldr.ToString());
}
【问题讨论】:
-
在询问时间复杂度之前,请确保算法正确。是的,针对stackoverflow.com/questions/4137986/… 发布了一个算法,但该答案上的 cmets 表明该算法不完整。在某些情况下它会给出错误的答案。
-
是的,大卫。我阅读了那些 cmets,并且在我的逻辑中注意了一些条件。也许我可以在我的描述中提到这一点。例如。我正在检查 resultNode 不为零以进行另一个子矩阵递归调用。在大多数条件下进行了测试,但未在此处发布所有条件。我尚未考虑优化的一点来自我的例如如果我在子矩阵 (1,4,2,5) 中查找 3,它将首先与 1,2,4 进行比较,因为 3 小于 5。如果 (1,4,2) 会进行更多不必要的检查,5) 和 3 在大约 X 百万矩阵中的十万行。感谢您强调。
-
我们很多人都知道的一个最简单的方法是,如果矩阵是 n(列)X m(行)并且 n > m。然后对 m(行)线性重复循环并在 n(列)上应用二进制搜索。所以这将是 O(m log n)。但我正在努力。
标签: algorithm recursion data-structures matrix recursive-datastructures