算法 - 最长路径网格拼图

时间:2014-12-04 05:49:59

标签: algorithm

所以情况是:
 1.有NxN网格,所以它是一个方形网格
 2.将给出最大量的步骤  3.网格内的每个单元都有一定的数值​​,这将减少步骤的最大数量 我们只能向右和向下移动 5.起点位于网格的左上角,目标是网格的右下角 6.我们需要确定最长的路径(剩下最大步数的路径) 7.如果没有可能的路径,结果将为-1

所以目前我已经编写了一个代码,它可以处理某些情况,但仍然不是最佳情况 我现在正在做的是:
1.检查下一个正确的值和下一个值是否正确 2.去更大的价值 3.如果最大步数变为0回溯到前一个单元格并向另一个方向移动 4.如果正确的值和以下值相同,我将检查下一个单元格后的下一个单元格。

看起来问题出在第4点。

这是我的第4点代码:

private static int determineBestNext(int[][] grid, int currentX, int currentY) {
    int nextRight = 0;
    int nextBelow = 0;
    int numberOfRows = grid.length - 1;
    for(int i=currentX+1;i<numberOfRows-1;i++) {
        nextRight += grid[currentY][i+1];
        if(currentY != numberOfRows) {
            nextRight += grid[currentY+1][i+1];
        }
    }
    for(int i=currentY+1;i<numberOfRows-1;i++) {
        nextBelow = grid[i+1][currentX];
        if(currentX != numberOfRows) {
            nextBelow += grid[i+1][currentX+1];
        }
    }
    if(nextRight > nextBelow) {
        return 1;
    } else if (nextBelow > nextRight) {
        return 2;
    } else {
        return determineBestNext(grid, currentX+1,currentY+1);
    }
}

我猜回落是当X大于Y时,Y中的步数越大,因此Right值大于X的机会,反之亦然。

你们有另一个想法吗?谢谢!

谢谢!

2 个答案:

答案 0 :(得分:1)

您可以在O(n^2)中找到最佳路径。我将调用(1,1)左上角的单元格(起始点),网格(i,j)将是单元格的值。并且步骤(i,j)是到达单元(i,j)所需的最小步骤数。

您可以快速识别关系

steps(i,j) = min(steps(i-1,j), steps(i,j-1)) + grid(i,j)  // if i,j > 1

如果i = 1j = 1i = j = 1更容易,因为那时只有一条可能的路径。

因此我们想要计算steps(N,N),我们得到steps(N,N) = min(steps(N-1,N), steps(N,N-1)) + grid(N,N)。对于计算,我们需要steps(N-1,N)steps(N,N-1)。所以steps(N-1,N) = min(steps(N-2,N), steps(N-1,N-1)) + grid(N-1,N)steps(N,N-1) = min(steps(N-1,N-1), steps(N,N-2)) + grid(N,N-1)。我们看到,对于每个结果,我们都需要steps(N-1,N-1)的值。两次计算这个值会是一个腰部。如果我们只计算一个并记住该值,我们可以保存一个计算。这些事情经常发生。

记住最好的方法是有一个固定的评估顺序。 这里有一些伪代码:

function getBestPath(grid, N)
    steps = new N x N int-array //initialized with 0

    //first row
    steps[0][0] = grid[0][0] 
    // only one path to get to (0,0), it's doing nothing
    for (i = 1; i < N; i++)
        steps[0][i] = steps[0][i-1] + grid[0][i] 
        // only one path each, just going right

    //other rows
    for (row = 1; row < N; row++)
        steps[row][0] = steps[row-1][0] + grid[row][0] 
        //only one way to get to (row,0), only go down

        for (i = 1; i < N; i++)
            steps[row][i] = min(steps[row-1][i], steps[row][i-1]) + grid[row][i]

    return steps[N-1][N-1]

答案 1 :(得分:0)

第7点让我觉得你错过了一些细节。

什么时候没有路径?假设步骤数量必须是非负的吗?

如果没有,则路径始终是可能的,并且可以使用简单的动态编程O(N ^ 2)算法,如另一个答案所示。

您是否试图通过修改问题并错过流程中的重要细节来欺骗某些编程测试?