java - 递归头痛

标签 java arrays recursion

任务:

给定一个包含非负整数的二维数组m,我们将“路径”定义为相邻单元格的集合(对角线步骤不算作邻居) 从row == 0 && col == 0 开始到row == m.length - 1 && col == m[0].length - 1.

“路径”的成本是“路径”每个单元格中值的总和。

示例:

数组中的两个可能路径: possible paths in an array

路径1(虚线)的成本:8 + 4 + 2 + 8 + 9 + 9 + 7 + 5 = 52;

路径 2(全线)的成本:8 + 6 + 3 + 8 + 9 + 4 + 1 + 2 + 1 + 7 + 6 + 5 = 60

待办事项:

编写一个static 递归方法,它接受一个二维数组m,其中填充了完整的非负值,并打印所有可能路径的总和成本(您可以假设 m 既不是 null 也不是空的)。

方法签名是(允许重载):

public static void printPathWeights(int [][] m)

我的代码:

public class Main {

    public static void main(String[] args) {

        int arr[][] = { { 1, 1, 1 },
                        { 1, 1, 1 },
                        { 1, 1, 1 }
        };

        printPathWeights(arr);

    }

    public static void printPathWeights(int[][] m) {
        System.out.println(printPathWeights(m, 0, 0, new int[m.length][m[0].length], 0));
    }


    /*
     * @param map marks the visited cells
     */
    private static int printPathWeights(int[][] m, int row, int col, int[][] map, int carrier) {

        if (row < 0 || col < 0 || row >= m.length || col >= m[0].length || map[row][col] == 1)
            return 0;

        if (row == m.length - 1 && col == m[0].length - 1)
            return m[row][col] + carrier;

        map[row][col] = 1;
        return printPathWeights(m, row + 1, col, map, carrier + m[row][col]) +
                printPathWeights(m, row - 1, col, map, carrier + m[row][col]) +
                printPathWeights(m, row, col + 1, map, carrier + m[row][col]) +
                printPathWeights(m, row, col - 1, map, carrier + m[row][col]);

    }

}

以上代码的打印值为:14

低于预期!

运行时:

    int arr[][] = { { 1, 1 },
                    { 1, 1 }
    };

结果是预期的 6。

我的代码有什么问题?

PS:请不要向我提供解决作业的代码,但请解释我的代码有什么问题。

最佳答案

只要任意路径到达该单元格,该代码就会标记已访问的单元格。但是此单元格随后也被标记为所有其他单元格已访问,并且不会再次访问。这意味着该算法仅完成路径的一个子集,并且对于更大的数组,一些遍历会在数组中间的某个地方中断。您必须为每条路径分别将单元格标记为已访问。

每次访问新单元格后简单地重置 map :

    printPathWeights(...)
        //analyze the current cell
        markCellVisited(currentCell)

        int tmp = visitAllNeighbours()

        resetVisitedState(currentCell)

        return tmp

这将是最有效和最简单的方法。由于 cellstate 在访问 cell 后被重置,因此它永远不会保留之前路径的标记。

关于java - 递归头痛,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31162213/

相关文章:

arrays - 打印 True 或 False

arrays - 包含整数的数组的排列变体

java - 将 ArrayList 中的多个元素放入单个数组?

ruby-on-rails - 使用 Ruby 通过嵌套 JSON 对象进行过滤并获取具有特定键的 JSON

java - DataOutput.writeByte()/DataInput.readByte() 或其他等效项在 Java 中如何工作?

python - Karatsuba算法太多递归

c - 如何避免 C 中字符串递归函数中的段错误?

java - 从 ArrayList 中捕获重复项

java - 如何将对象数组添加到列表中

java - Spring Boot 服务层单元测试中模拟原始字符串