【问题标题】: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] 的最小值。)
  • 请解释什么是成本属性。显然不允许使用负值。对吗?

标签: algorithm dynamic-programming


【解决方案1】:

如果我正确理解您的问题,A* 可能会为您提供最佳运行时。对于每个 ii+1 到 i+M 将是子节点,而 h 将是从 iN 的成本,假设每个后续节点的成本为 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 方法,但不确定,它是否正确.所以,首先让我为你检查一下,然后我会在完成后分享。 :)
    • 它被用于校内编码竞赛。所以,很抱歉,但无法从大学网络之外访问它。
    • 好的。告诉我应该在这里自己给出解决方案还是为其创建新的答案部分。
    • 您可以编辑您的原始答案以添加新的解决方案,以便在正确的情况下对其进行投票。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-13
    • 1970-01-01
    • 2021-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多