Algorithm 在矩阵运行时comlexity中搜索单词

Algorithm 在矩阵运行时comlexity中搜索单词,algorithm,time-complexity,Algorithm,Time Complexity,尝试分析以下算法的运行时复杂性: for(int i = 0; i < m; i++){ for(int j = 0; j < n; j++){ if(A[i][j] is equal to the starting character in s) search(i, j, s) } } boolean search(int i, int j, target s){ if(the current position relative to s

尝试分析以下算法的运行时复杂性:

for(int i = 0; i < m; i++){
    for(int j = 0; j < n; j++){
        if(A[i][j] is equal to the starting character in s) search(i, j, s)
    }
}

boolean search(int i, int j, target s){
    if(the current position relative to s is the length of s) then we find the target
    looping through the four possible directions starting from i, j: {p,q} = {i+1, j} or {i-1, j} or {i, j+1} or {i, j-1}, if the coordinate is never visited before
    search(p, q, target s)
}


问题:我们有一个
m*n
数组
A
,由小写字母和目标字符串
s
组成。目标是检查目标字符串是否出现在
A

算法:

for(int i = 0; i < m; i++){
    for(int j = 0; j < n; j++){
        if(A[i][j] is equal to the starting character in s) search(i, j, s)
    }
}

boolean search(int i, int j, target s){
    if(the current position relative to s is the length of s) then we find the target
    looping through the four possible directions starting from i, j: {p,q} = {i+1, j} or {i-1, j} or {i, j+1} or {i, j-1}, if the coordinate is never visited before
    search(p, q, target s)
}


for(int i=0;i
我读到的一个运行时复杂性分析如下:

在数组
A
中的每个位置,我们首先会看到
4
可能的探索方向。第一轮之后,我们只有3个可能的选择,因为我们再也回不去了。因此,最糟糕的运行时复杂性是
O(m*n*3**len(s))

然而,我不同意这一分析,因为尽管我们每轮只能看到3个可能的选择,但我们确实需要花一次手术来检查之前是否访问过该方向。例如,在java中,您可能只是使用一个布尔数组来跟踪一个点之前是否被访问过,因此为了知道一个点是否被访问过,需要进行一次条件检查,这需要一次操作。我提到的分析似乎没有考虑到这一点

运行时的复杂性应该是什么

更新:

假设目标字符串的长度为
l
,矩阵中给定位置的运行时复杂性为
T(l)
。然后我们有:

T(l)=4t(l-1)+4=4(3T(l-2)+4)+4=4(3(3T(l-3)+4)+4+4=4*3**(l-1)+4+4*4+4*3*4+…

+4
来自这样一个事实,即我们在每一轮中循环四个方向,除了递归调用自己三次之外

运行时的复杂性应该是什么

上述分析是正确的,复杂性确实是
O(m*n*3**len(s))

例如,在java中,您可能只是使用一个布尔数组来跟踪一个点之前是否被访问过,因此为了知道一个点是否被访问过,需要进行一次条件检查,这需要一次操作

这是正确的,与分析不矛盾


我们可以构造的最坏情况是矩阵中只填充了一个字母
a
和一个字符串
aaaa….aaaaaax
(许多字母
a
和一个
x
)。如果
m
n
len(s)
足够大,则
search
函数的几乎每个调用都将生成3个自身递归调用。每个调用将生成另外3个调用(总共9个深度为2的调用),每个调用将生成另外3个调用(总共27个深度为3的调用),依此类推。检查当前字符串、条件检查、生成递归都是
O(1)
,所以整个
search
函数的复杂性是
O(3**len(s))

谢谢您的回答,但我不太明白为什么检查当前字符串、条件检查、生成递归都是
O(1)
。如果我们把它们都加在一起,我不认为它仍然是
O(1)
。我添加了一个更新来解释。@penny Big-O表示法不关心常数的乘法(或加法)。也就是说,
O(a*f(n)+b)=O(f(n))
对于任何
a>0
b>0
。看看情况是否如此,然后
O(T(n))=O(T(n-1))=O(T(1))=O(1)
这感觉不太对。@penny这确实不对。
..
中的零件数量取决于
n
,因此如果
n
受到限制(这意味着它本质上是一个常数),您可以实际编写该等式。但是Big-O表示法是关于渐近分析的,也就是说,
n
可能是任意大的,并且方程没有意义。您应该可以在
n
上编写(有限)方程,而无需假设即可使其工作。