当前位置: 首页 > 面试题库 >

Java-通过2D数组的路径中的最大和

戚均
2023-03-14
问题内容

基本上我有一个类似于以下问题:

有一个以2D正方形阵列表示的草莓植物花园。每棵植物(每个元素)都有许多草莓。您从数组的左上角开始,并且只能向右或向下移动。我需要设计一种递归方法来计算通过花园的路径,然后输出产量最高的草莓。

我认为我对非常简单的递归问题有所了解,但是这个问题已经超出了我的范围。我真的不确定创建递归方法的起点或终点。

非常感谢与代码相关的任何帮助或帮助我理解此问题背后的概念。谢谢。


问题答案:

就像dasblinkenlight所说的那样,最有效的方法是使用记忆或动态编程技术。我倾向于动态编程,但是在这里我将使用纯递归。

答案围绕着一个基本问题的答案:“如果我在场上的r行和c列的正方形中,如何评估从左上到此处的路径,以使草莓的数量最大化? ”

要实现的关键是,只有两种方法可以获取r行和c列中的图:要么我可以使用r-1行和c列中的图从上方到达那里,要么可以从侧面到达,使用r行和c-1列中的图。之后,您只需要确保您知道基本情况即可……从根本上讲,这意味着我的纯递归版本将类似于:

int[][] field;    
int max(int r, int c) {
    //Base case
    if (r == 0 && c == 0) {
        return field[r][c];
    }
    //Assuming a positive number of strawberries in each plot, otherwise this needs
    //to be negative infinity
    int maxTop = -1, maxLeft = -1;
    //We can't come from the top if we're in the top row
    if (r != 0) {
        maxTop = field[r-1][c];
    }
    //Similarly, we can't come from the left if we're in the left column
    if (c != 0) {
        maxLeft = field[r][c-1];
    }
    //Take whichever gives you more and return..
    return Math.max(maxTop, maxLeft) + field[r][c];
}

致电max(r-1,c-1)以获得答案。注意这里效率很低。通过使用动态编程(我将在下面提供)或备忘录(已经定义),您会做得更好。不过,要记住的是,DP和备忘录技术都是从此处使用的递归原理获得的更有效的方法。

DP:

int maxValue(int[][] field) {
    int r = field.length;
    int c = field[0].length;
    int[][] maxValues = new int[r][c];
    for (int i = 0; i < r; i++) {
        for (int j = 0; j < c; j++) {
            if (i == 0 && j == 0) {
                maxValues[i][j] = field[i][j];
            } else if (i == 0) {
                maxValues[i][j] = maxValues[i][j-1] + field[i][j];
            } else if (j == 0) {
                maxValues[i][j] = maxValues[i-1][j] + field[i][j];
            } else {
                maxValues[i][j] = Math.max(maxValues[i][j-1], maxValues[i-1][j]) + field[i][j];
            }
        }
    }
    return maxValues[r-1][c-1];
}

在这两种情况下,如果您想重新创建实际路径,只需保留一个二维布尔值表即可,它对应于“我来自上方还是左侧”?如果最草莓路径来自上方,则为true,否则为false。这样可以让您在计算后重新跟踪补丁。

请注意,这原则上仍然是递归的:在每个步骤中,我们都在回顾以前的结果。我们正好是在缓存我们以前的结果,所以我们不会浪费很多工作,而且我们正在以智能顺序攻击子问题,以便我们始终可以解决它们。有关动态编程的更多信息,请参见Wikipedia。



 类似资料:
  • 我正在调试以下问题并发布代码。不知道代码是否正确。我目前的疑问是,是否应该一直增加(在这一行--

  • 问题内容: 我想输出二维数组的最大值和最小值。Max可以很好地工作,但是即使在数组中没有零的情况下min也总是输出零。在本例中,我设置为99以防止较小的机会在数组中获得零。继承人完整代码: 问题答案: 由于您在中选择随机值的方式,不会存在小于零的值- 但也无法保证任何值都将恰好为零。但是,您将初始化为零,因为这是数组元素的默认值;没有什么比这更小了,所以答案总是零。 您应该在标记为“查找最小值”的

  • 给定二维正整数数组。“路径”是相邻单元格的集合。两个单元格仅从右/左/上/下(无对角线)相邻。 任务是编写一个函数,用于接收2D数组、整数和2D数组路径(与mat大小相同-空数组均为零)。 函数应检查单元格总和等于sum的路径是否存在,如果存在,则应返回true,否则返回false。 数组路径将标记路径(如果存在路径,则标记路径为1)。 例如,如果mat是: 和总和=4 然后,路径可以是以下三种路

  • 这里, S=起点(2,2) B=块 O=打开 X=出口 我想做一个迷宫,可以检查北部,西部,东部和南部。如果X在附近,它将返回程序。如果没有,则检查起点周围的任何“O”,并以递归方式传递新的起点。它没有办法去,“X”没有找到,它将回到原来的起点(2,2)并检查西部,东部和南部。 节目结束后,我得到了: 但是,我期望递归后的输出是: 这是我现在的代码: startX和startY是起点的索引。 我不

  • 问题内容: 我的代码没有给出错误,但是没有显示最小值和最大值。代码是: 我是否需要system.out.println()来显示它,否则返回应该起作用吗? 问题答案: 您正在调用方法,但不使用返回的值。

  • 问题内容: 我想知道打印2D阵列的最佳方法是什么。这是我的一些代码,我只是想知道这是否是一种好习惯。如果发现任何其他错误,请更正我在此代码中犯的任何其他错误。谢谢! 问题答案: 你可以用简单的方式打印。 在下面使用以打印2D阵列 在下面使用以打印一维阵列