这可以用线性时间复杂度解决吗?
Posted
技术标签:
【中文标题】这可以用线性时间复杂度解决吗?【英文标题】:Can this be solved in linear time complexity? 【发布时间】:2015-09-10 22:49:48 【问题描述】:给定一个由 N 个整数组成的数组(元素为正数或 -1),以及另一个整数 M。 对于每个 1 ,我们可以跳转到数组的 i + 1, i + 2, .. i + M 索引。从索引 1 开始,有一个线性 O(N) 算法,可以找出最小成本以及到达 Nth 索引的路径。其中成本是从 1 到 N 的路径中所有元素的总和。我有一个复杂度为 O(N*M) 的动态规划解决方案。 注意:如果 A[i] 为 -1,则表示我们无法登陆第 ith 索引。
【问题讨论】:
非负值是走这条路的成本吗?否则,这是一个微不足道的贪心算法:尽可能跳(向后搜索来自A[i+M]
的非负条目),直到i+M >= N
。
如果数组值是成本,那么你有一个图问题,有向无环图。每个节点A[i]
连接到所有具有非负索引的节点A[i+1 .. i+M]
。您存储图形的方式可能对寻路算法有利也可能不利,但转换为另一种表示形式可以在线性时间内完成。
我认为 O(NM) 复杂度的动态规划解决方案。即使你用一个图,这个图的节点也是O(mn)...
@kaitian:有 N 个节点,但有 O(N*M)
边。问题是是否有办法利用冗余:进入A[i]
的所有边具有相同的成本。显然,您可以非常快速地找到 a 路径,甚至可以对其进行一些细化以找到局部最小值。 (启发式取决于预期的成本分布。例如,找到A[i+M-16 .. i+M]
的最小值。)
请解释什么是成本属性。显然不允许使用负值。对吗?
【参考方案1】:
如果我正确理解您的问题,A* 可能会为您提供最佳运行时。对于每个 i,i+1 到 i+M 将是子节点,而 h 将是从 i 到 N 的成本,假设每个后续节点的成本为 1(例如,如果 N=11 M=4 然后 h=3 for i=2,因为这是到达最终索引所需的最少跳转次数) .
【讨论】:
【参考方案2】:新方法
Assumption
:该图不是加权图。
这种解释方法可以在线性时间内解决问题。 所以,算法如下。
int A[N]; // It contains the initial values
int result[N]; // Initialise all with positive infinty or INT_MAX in C
bool visited[N]; // Initially, all initialise with '0' means none of the index is visited
int current_index = 1
cost = 0
result[current_index] = cost
visited[current_index] = true
while(current_index less than N)
cost = cost + 1 // Increase the value of the cost by 1 in each level
int last_index = -1 /* It plays the important role, it actually saves the last index
which can be reached form the currnet index, it is initialised
with -1, means it is not pointing to any valid index*/
for(i in 1 to M)
temp_index = current_index + i;
if(temp_index <= N AND visited[temp_index] == false AND A[temp_index] != -1)
result[temp_index] = cost
visited[temp_index] = true
last_index = temp_index
if(last_index == -1)
print "Not possible to reach"
break
else
current_index = last_index
// Finally print the value of A[N]
print A[N]
做,当你完成这个方法时告诉我。
================================================ ============================
以前的方法
虽然,这种解释方法也是非线性的。但相信我,它会比你的动态方法更有效。因为在您的方法中它总是需要 O(N.M) 时间,但在这里它可以减少到 O(n.M),其中 n 是数字数组中具有 no -1
值的元素。
Assumption:
在这里,我认为 A[1] 和 A[N] 的值不是-1
。而且,数组中连续的-1
值不 多于M-1 个。否则,我们无法完成这项工作。
现在,进行如下描述的BFS:
int A[N]; // It contains the initial values
int result[N]; // Initialise all with positive infinty or INT_MAX in C
bool visited[N]; // Initially, all initialise with '0' means none of the index is visited
queue Q; // create a queue
index = 1
cost = 0
push index in rear of Q.
result[index] = cost
visited[index] = true
while(Q is not empty)
index = pop the value from the front of the Q.
cost = cost + 1
for(i in 1 to M)
temp_index = index + i;
if(temp_index <= N AND visited[temp_index] == false AND A[temp_index] != -1)
push temp_index in rear of Q.
result[temp_index] = cost
visited[temp_index] = true
// Finally print the value of A[N]
print A[N]
注意:最坏情况下的时间复杂度与 DP 相同。 对算法有任何疑问,欢迎 cmets。而且,如果有人比我有更好的方法,请分享。 毕竟,我们是来学习的。
【讨论】:
是的,bfs也可以用来解决这个问题,但是最坏情况的复杂度仍然没有提高。 @PrakharAgarwal 这个问题在哪个网站上,你能给我它的链接吗,因为我有一个 linear 方法,但不确定,它是否正确.所以,首先让我为你检查一下,然后我会在完成后分享。 :) 它被用于校内编码竞赛。所以,很抱歉,但无法从大学网络之外访问它。 好的。告诉我应该在这里自己给出解决方案还是为其创建新的答案部分。 您可以编辑您的原始答案以添加新的解决方案,以便在正确的情况下对其进行投票。以上是关于这可以用线性时间复杂度解决吗?的主要内容,如果未能解决你的问题,请参考以下文章