Longest Increasing Sequence 2D matrix recursion

后端 未结 4 1289

I have been presented with a new homework assignment that has been somewhat frustrating to say the least. Basically, I have a create a 2D array of integers as follows:

相关标签:
4条回答
  • 2020-12-23 23:01

    java complete solution It returns pathes to console, and returns longest sequence, but you can little modify this code, and you'll get longest path also

    public class HedgehogProblemSolver {
    
    private int rowCount;
    private int columnCount;
    private int[][] fieldArray;
    private int maxApplesCount = 0;
    
    public HedgehogProblemSolver(int inputArray[][]) {
        this.fieldArray = inputArray;
        rowCount = inputArray.length;
        columnCount = inputArray[0].length;
    }
    
    public int solveProblem() {
        findPathRecursive(0, 0, "", 0);
        System.out.println("Max apple count: " + maxApplesCount);
        return maxApplesCount;
    }
    
    private void findPathRecursive(int row, int column, String path, int applesCount) {
        if (row == rowCount - 1) {
            //last row
            for (int i = column; i < columnCount; i++) {
                //just go right until last column
                path += "-[" + fieldArray[row][i]  + "](" + row + ", " + i + ")";
                applesCount += fieldArray[row][i];
            }
            pathResult(path, applesCount);
            return;
        }
        if (column == columnCount - 1) {
            //last column
            for (int i = row; i <= rowCount - 1; i++) {
                //just go down until last row
                path += "-[" + fieldArray[i][column] + "](" + i + ", " + column + ")";
                applesCount += fieldArray[i][column];
            }
            pathResult(path, applesCount);
            return;
        }
    
        path = path + "-[" + fieldArray[row][column] + "](" + row + ", " + column + ")";
        applesCount += fieldArray[row][column];
    
        //go down
        findPathRecursive(row + 1, column, path, applesCount);
        //go right
        findPathRecursive(row, column + 1, path, applesCount);
    }
    
    private void pathResult(String path, int applesCount) {
        System.out.println("Path: " + path + "; apples: " + applesCount);
        if (applesCount > maxApplesCount) {
            maxApplesCount = applesCount;
        }
    }
    
    }
    
    0 讨论(0)
  • 2020-12-23 23:06

    Another approach: Sort the matrix entries by the value in them. Iterate from the largest to the smallest. For each entry, compute the longest path in constant time: longest path is 1 + maximum over longest paths for larger neighbors (which have already been computed).

    Total time: O(mn log(mn)) to sort the matrix entries, plus O(mn) to find the longest paths.

    0 讨论(0)
  • 2020-12-23 23:17

    Update

    I learnt dynamic programming recently, and I have found a better algorithm for the question.

    The algorithm is simple: find the longest length for every point, and record the result in a 2D array so that we do not need to calculate the longest length for some points again.

    int original[m][n] = {...};
    int longest[m][n] = {0};
    
    int find() {
        int max = 0;
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                int current = findfor(i, j);
                if (current > max) { max = current; }
            }
        }
        return max;
    }
    
    int findfor(int i, int j) {
        if (longest[i][j] == 0) {
            int max = 0;
            for (int k = -1; k <= 1; k++) {
                for (int l = -1; l <= 1; l++) {
                    if (!(k == 0 && l == 0) &&
                        i + k >= 0 && i + k < m &&
                        j + l >= 0 && j + l < n &&
                        original[i + k][j + l] > original[i][j]
                       )
                        int current = findfor(i + k, j + l);
                        if (current > max) { max = current; }
                    }
                }
            }
            longest[i][j] = max + 1;
        }
        return longest[i][j];
    }    
    

    Recursion

    1) start with a point (and this step has to be taken for all necessary points)

    2) if no surrounding point is greater, then this path ends; else pick a greater surrounding point to continue the path, and go to 2).

    2.1) if the (ended) path is longer than recorded longest path, substitute itself as the longest.


    Hint

    (less computation but more coding)

    For the longest path, the start point of which will be a local minimum point, and the end point of which will be a local maximum point.

    Local minimum, less than (or equal to) all (at most) 8 surrounding points.

    Local maximum, greater than (or equal to) all (at most) 8 surrounding points.

    Proof

    If the path does not start with a local minimum, then the start point must be greater than at least a surrounding point, and thus the path can be extended. Reject! Thus, the path must start with a local minimum. Similar for the reason to end with a local maximum.


    pseudo code

    for all local minimum
      do a recursive_search
    
    recursive_search (point)
      if point is local maximum
        end, and compare (and substitute if necessary) longest
      else
        for all greater surrounding points
          do a recursive_search
    
    0 讨论(0)
  • 2020-12-23 23:21

    I know this is a very old question, but, I'm reading Lubomir Stanchev's book titled Learning Java Through Games, and the Chapter 14 Project is that exact 2D array of integers. The assignment is to find the longest increasing sequence but only in two directions, South and East, no diagonals or anything. Still it took me hours to figure out the logic, not used to the recursion either. I simplified the problem by creating auxiliary methods that check if the next index is valid in that direction (that is, not out of bounds and greater than the current value). Then I placed the base case at the start of the method, which is when there is no next possible index. The tricky part is the assignment of the String variable, so each time the method uses recursion the indexes are saved in the String. I solved it by using the String.length() method to compare the length of each sequence, when there is more than one possible path. With the basic logic in place, in order to expand the method all that it would require is creating more auxiliary methods in the direction needed, and adding those directions to the logic.

    public static boolean isRightLegal(int[][] array, int row, int column) {
        //if we are at the last column
        if (column >= array[row].length - 1) {
            return false;
        }
        //if we are not at the one before last
        if ((column + 1) < array[row].length) {
            //if the current number is greater than the next
            if (array[row][column] > array[row][column + 1]) {
                return false;
            }
        }
        return true;
    }
    
    public static boolean isDownLegal(int[][] array, int row, int column) {
        //if we are at the last row
        if (row >= array.length - 1) {
            return false;
        }
        //if we are not at the one before last
        if ((row + 1) < array.length) {
            //if the current number is greater than the next
            if (array[row][column] > array[row + 1][column]) {
                return false;
            }
        }   
        return true;
    }
    
    public static String recursiveSequence(int[][] array, int row, int column, String path) {
        //base case: when we reach the end of the sequence
        if (! isDownLegal(array, row, column) && ! isRightLegal(array, row, column)) {
            return "(" + row + "," + column + ") ";
        }
        path = "(" + row + "," + column + ") ";
        //if both paths are valid
        if (isDownLegal(array, row, column) && isRightLegal(array, row, column)) {
            //calculate each sequence and pick the longest one
            if (recursiveSequence(array, (row + 1), column, path).length() > recursiveSequence(array, row, (column + 1), path).length()) {
                path += recursiveSequence(array, (row + 1), column, path);
            } else {
                path += recursiveSequence(array, row, (column + 1), path);
            }
            return path;
        }
        //if only the down path is valid
        if (isDownLegal(array, row, column)) {
            path += recursiveSequence(array, (row + 1), column, path);
        }
        //if only the right path is valid
        if (isRightLegal(array, row, column)) {
            path += recursiveSequence(array, row, (column + 1), path);
        }
        return path;
    }
    

    }

    0 讨论(0)
提交回复
热议问题