找到网格中最大总和从顶行向下移动的路径

时间:2014-01-13 04:18:41

标签: java recursion

我正在从“Java照明”这本书中做一个递归章节问题。我需要在正整数的矩形网格中找到具有最大总和的路径,从顶行的任何位置开始,并在每个后续步骤中直接向下或对角向下移动。

到目前为止,我已经能够计算出最大路径的实际总和。在以下网格中

02 05 17 12 03
15 08 04 11 10
09 18 06 20 16
14 13 12 01 07

我现有的代码将返回60。

如何以最大的总和返回(或打印出)PATH?即17 + 11 + 20 + 12 = 60

public class MaximumPath {

    public static int maxSum(int grid[][]){
        int r = grid.length - 1;        // bottom row #
        int c = grid[0].length - 1;     // rightmost column #
        int max = 0;
        for (int i=0; i <= c; i++){
            int val = maxSum(grid, r, i); // call recursive method for each of the bottom row cells
            if ( val > max) max = val;
        }
        return max;
    }

    public static int maxSum(int grid[][], int row, int col)
    // recursive method to find largest sum path to row,col, coming downwards from top
    {
       if (col < 0 || row < 0 || row > grid[0].length || col > grid.length) return 0;      
       else return grid[row][col] + max3(   maxSum(grid, row-1, col-1),         // top left
                                            maxSum(grid, row-1, col),           // top
                                            maxSum(grid, row-1, col+1) ) ;      // top right
    }

    public static int max3(int x, int y, int z) // return max of 3 numbers
    {
       if (x > y)
          return (x > z)? x : z;
       else
          return (y > z)? y : z;
    }

    public static void main(String[] args){
        int[][] grid = {{2, 5, 17, 12, 3}, 
                        {15, 8, 4, 11, 10}, 
                        {9, 18, 6, 20, 16}, 
                        {14, 13, 12, 1, 7}};
        System.out.println("Max sum is "+maxSum(grid));
    }
}

2 个答案:

答案 0 :(得分:0)

这是一个经典的编程问题。你需要找到Maximum Subarray

Wiki在一个维度上涵盖了算法。一旦理解了这一点,就可以很容易地扩展到2维。

答案 1 :(得分:0)

你遇到的问题是,由于递归的性质,你不知道哪条路径是正确的,直到最后。所以你必须随时存储每个路径(包括总数),只保留每行比较的最大路径。

这是我掀起的快速解决方案:

import java.util.*;

public class MaximumPath {

    // object to store both path and total
    public static class Pair {
        public ArrayList a;
        public int b;

        public Pair(ArrayList a, int b) {
            this.a = a;
            this.b = b;
        }
    };

    public static Pair maxSum(int grid[][]){
        int r = grid.length - 1;        // bottom row #
        int c = grid[0].length - 1;     // rightmost column #
        Pair max = null;
        for (int i=0; i <= c; i++){
            Pair val = maxSum(grid, r, i); // call recursive method for each of the bottom row cells
            if (max == null || val.b > max.b) max = val;
        }
        return max;
    }

    public static Pair maxSum(int grid[][], int row, int col)
    // recursive method to find largest sum path to row,col, coming downwards from top
    {
       if (col < 0 || row < 0 || row > grid[0].length || col > grid.length){           
           return new Pair(new ArrayList(), 0);           
       }else{
           // take the path pair with the max value so far
           Pair p = maxPair(maxSum(grid, row-1, col-1),         // top left
                            maxSum(grid, row-1, col),           // top
                            maxSum(grid, row-1, col+1) ) ;      // top right)            
           // add the current path value and total to the path
           p.a.add(grid[row][col]);
           p.b += grid[row][col];           
           return p;
       }       
    }

    public static Pair maxPair(Pair x, Pair y, Pair z)
    {
        if(x.b > y.b){
            return (x.b > z.b)? x : z;
        }else{
            return (y.b > z.b)? y : z;   
        }        
    }

    public static void main(String[] args){
        int[][] grid = {{2, 5, 17, 12, 3}, 
                        {15, 8, 4, 11, 10}, 
                        {9, 18, 6, 20, 16}, 
                        {14, 13, 12, 1, 7}};    
        Pair p = maxSum(grid);
        System.out.println("Max sum is " + p.b);
        System.out.println("Path is " + p.a);
    }
}