Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 排序矩阵搜索的复杂性_Algorithm_Matrix_Time Complexity - Fatal编程技术网

Algorithm 排序矩阵搜索的复杂性

Algorithm 排序矩阵搜索的复杂性,algorithm,matrix,time-complexity,Algorithm,Matrix,Time Complexity,假设我们有一个大小为NxN的数字矩阵,其中所有行和列的顺序都是递增的,我们想知道它是否包含一个值v。一种算法是在中间行上执行二进制搜索,以查找与v:M[row,col]T(n)=T(n/2)+log(n^(1/2)) =>T(n)=T(n/2)+1/2*log(n) 这里,a=1,b=2。 因此,c=logb(a)=log2(1)=0 =>n^c=n^0 而且,f(n)=n^0*1/2*log(n) 根据, T(n)=O((log(n))^2)假设我们有以下矩阵: 1 2 3 4 5 6 7 8

假设我们有一个大小为NxN的数字矩阵,其中所有行和列的顺序都是递增的,我们想知道它是否包含一个值v。一种算法是在中间行上执行二进制搜索,以查找与v:M[row,col] 问题是这个算法的复杂性是什么

示例:假设我们有如下所示的5x5矩阵,并且我们正在搜索数字25:

0 10 20 30 40
1 11 21 31 41
2 12 22 32 42
3 13 23 33 43
4 14 24 34 44
在第一次迭代中,我们对中间一行执行二进制搜索,发现小于25的最近元素是22(行=2列=2)。现在我们知道25比左上角3x3象限中的所有项目都大:

0 10 20
1 11 21
2 12 22
32 42
33 43
34 44
同样,我们知道25比右下角3x2象限中的所有元素都小:

0 10 20
1 11 21
2 12 22
32 42
33 43
34 44
因此,我们递归搜索剩余象限-右上角2x2:

30 40
31 41
左下角2x3:

3 13 23
4 14 24
等等。我们基本上将矩阵划分为4个象限(根据中间行的二进制搜索结果,大小可能不同),然后递归搜索其中两个象限。

此算法的复杂性为-:

O(log2(n*n)) =O(log2(n))

这是因为您在一次迭代中消除了矩阵的一半。

编辑-:

递推关系-:

假设
n
是矩阵中元素的总数

=>
T(n)=T(n/2)+log(sqrt(n))

=>
T(n)=T(n/2)+log(n^(1/2))

=>
T(n)=T(n/2)+1/2*log(n)

这里,
a
=1,
b
=2。 因此,
c
=logb(a)=log2(1)=0
=>
n^c=n^0

而且,
f(n)=n^0*1/2*log(n)

根据,


T(n)=O((log(n))^2)

假设我们有以下矩阵:

1 2 3
4 5 6
7 8 9
让我们使用指定的二进制搜索来搜索值
7

搜索最接近中间行
7
的值:
4 5 6
,即
6
。 嗯,我们有个问题,
7
不在以下子矩阵中:

6
9
那怎么办呢?一种解决方案是对所有行应用二进制搜索,其复杂性为
nlog(n)
。因此,沿着矩阵走是一个更好的解决方案

编辑:

递归关系:

T(N*N) = T(N*N/2) + log(N)
如果我们使用
M=N^2
将函数规格化为一个变量:

T(M) = T(M/2) + log(sqrt(M))
T(M) = T(M/2) + log(M)/2
根据主定理案例#2,复杂性为

(log(M))^2
=> (2log(N))^2
=> (log(N))^2
编辑2:

很抱歉,我在手机上回答了您的问题,现在当您思考时,
M[0…行-1,列+1…N-1]
没有多大意义,对吗?考虑一下我的例子,如果你搜索一个比中间行中所有值都小的值,你总是以最左边的数字结尾。类似地,如果搜索一个大于中间行中所有值的值,最终将得到最右边的数字。因此,该算法可以改写如下:


使用返回
1的自定义二进制搜索搜索中间行,如果在n步之后找到元素,则可搜索范围的大小为n=4^n。然后,时间复杂度为O(N的对数基4)=O(对数N/对数4)=O(0.5*logn)=O(对数N)


换句话说,您的算法比二进制搜索快两倍,后者等于O(logn)

关于对矩阵进行二进制搜索的考虑:

2D
矩阵和一般
ND
矩阵的二进制搜索与对排序的1D向量的二进制搜索没有什么不同。例如,事实上C以行主方式存储它们(作为:[[row0]、[row1]…[rowk]]中的行的集合) 这意味着可以使用众所周知的矩阵二进制搜索,如下所示(复杂度
log(n*m)
):

模板
布尔二进制搜索_2D(T目标,T**矩阵){
int a=0;int b=NCELLS-1;//行*COLS
bool-found=false;
while(!found&&a v)
a=一半+1;
else//target
最坏情况下的运行时间是θ(n)。当然,这和正确的算法一样好(考虑反对角线,上面的元素小于v,下面的元素大于v)。就上界而言,n行m列矩阵的上界是O(n log(2+m/n)),正如正确的递归所证明的那样

                  m-1
f(n, m) = log m + max [f(n/2, j) + f(n/2, m-1 - j)],
                  j=0
其中有两个子问题,而不是一个子问题。此递归可通过替换方法解决

        ?
f(n, m) ≤ c n log(2 + m/n) - log(m) - 2  [hypothesis; c to be chosen later]

                  m-1
f(n, m) = log m + max [f((n-1)/2, j) + f((n-1)/2, m-j)]
                  j=0

                    m-1
        ≤   log m + max [  c (n/2) log(2 + j/(n/2)) - log(j) - 2
                         + c (n/2) log(2 + (m-j)/(n/2))] - log(m-j) - 2]
                    j=0

        [fixing j = m/2 by the concavity of log]

        ≤ log m + c n log(2 + m/n) - 2 log(m/2) - 4

        = log m + c n log(2 + m/n) - 2 log(m) - 2

        = c n log(2 + m/n) - log(m) - 2.
将c设置得足够大,以便对于所有n,m

c n log(2 + m/n) - log(m) - 2 ≥ log(m),

其中log(m)是基本情况n=1的成本。

您可以使用递归函数并应用主定理来查找复杂性

假设
n
是矩阵中的元素数。 一步的成本是在
sqrt(n)
元素上进行二进制搜索,您会遇到两个问题,在最坏的情况下,每个问题的大小都相同,有n/4个元素:
2*T(n/4)
。因此我们有:

T(n)=2*T(n/4)+log(sqrt(n))

等于

T(n)=2*T(n/4)+log(n)/2

现在应用案例1(
a=2
b=4
f(n)=log(n)/2
f(n)in O(n^log_b(a))=O(n^(1/2))
,因此我们有案例1)

=>总运行时间
T(n)
O(n^(a/b))
=
O(n^(1/2))

或等于

O(sqrt(n))


如果两边相同,则等于矩阵的高度或宽度。

您想要什么?时间复杂度,或(与其他算法相比的效率)时间复杂度比较