剑指 Offer II 112. 最长递增路径

120 阅读1分钟

剑指 Offer II 112. 最长递增路径

image.png

  • var dp = new Array(m).fill(0).map(() => new Array(n).fill(0));这里的模型是记录已经处理过的i,j位置,如果值不为0说明是过的,防止重复处理,就直接返回该值
  • ans = Math.max(ans, f(i, j, -1)) 求出到i,j这个位置的最长递增路径长度,题目要求的是arr中每一个元素都是 >0的,所以这里写-1是防止arr[i][j] <= lastNum生效返回0,因为最长递增路径长度 >=1的
  • 使用dp[i][j]去记录处理过的i,j位置值,防止重复计算
  • for (var [x, y] of brr) { 上下左右四个方向到i,j这个位置,是否引起最长递增序列,每个都要考虑下
  • var value = f(ix, jy, arr[i][j]) + 1;if (i < 0 || j < 0 || i >= m || j >= n || arr[i][j] <= lastNum) return 0;,就是说,如果arr[i][j] <= 其他四个方向的值(例如:arr[i-1][j]),那么返回0代表的是,不形成递增关系,初步判断当前i,j这个位置的值就是最长底层序列的第一个位置,当然了这只是其中一个方向的初步判断,还需要进一步判断其他方向的
  • 如果形成了最长子序列,那么更新最值
var longestIncreasingPath = function (arr) {
    var [m, n] = [arr.length, arr[0].length];
    var dp = new Array(m).fill(0).map(() => new Array(n).fill(0));
    var brr = [[0, 1], [0, -1], [-1, 0], [1, 0]];
    var ans = 0;
    for (var i = 0; i < m; i++) {
        for (var j = 0; j < n; j++) {
            ans = Math.max(ans, f(i, j, -1))
        }
    }
    return ans;
    function f(i, j, lastNum) {
        if (i < 0 || j < 0 || i >= m || j >= n || arr[i][j] <= lastNum) return 0;
        if (dp[i][j]) return dp[i][j];
        var res = - Infinity;
        for (var [x, y] of brr) {
            var [ix, jy] = [i + x, j + y];
            var value = f(ix, jy, arr[i][j]) + 1;
            if (value > res) {
                res = value;
            }
        }
        dp[i][j] = res;
        return res;
    }
};
console.log(longestIncreasingPath([[9, 9, 4], [6, 6, 8], [2, 1, 1]]));