
链接:LintCode 炼码
题解:九章算法 - 帮助更多程序员找到好工作,硅谷顶尖IT企业工程师实时在线授课为你传授面试技巧
class Solution {
public:
    /**
     * @param matrix: A matrix
     * @return: An integer.
     */
    class Node {
    public:
        int x;
        int y;
        int val;
        Node(int ii, int jj, int v):x(ii), y(jj), val(v) {
        }
    };
    int longestIncreasingPath(vector<vector<int>> &matrix) {
        // Write your code here.
        if (matrix.size() <= 0) {
            return 0;
        }
        std::vector<Node> points;
        int m = matrix.size();
        int n = matrix[0].size();
        points.reserve(m*n);
        for (int i = 0; i < m; ++i) {
            for (int j = 0; j < n; ++j) {
                points.push_back(Node(i, j, matrix[i][j]));
            }
        }
        // 按照里面的数字进行排序
        sort(points.begin(), points.end(), [](Node& a, Node& b) {
            return a.val < b.val ? true : false;
        });
        // 到达当前下表i,j位置,最长路径长度
        std::vector<std::vector<int>> dp(m, std::vector<int>(n, 1));
        std::vector<std::vector<int>> direction{{0, -1}, {0, 1}, {1, 0}, {-1, 0}};
        // 从小到大进行遍历,遍历到当前位置,比他小的数字的长度都已经求解完成了
        for (int i = 0; i < points.size(); ++i) {
            // 当前点的坐标
            int x = points[i].x;
            int y = points[i].y;
            for (int j = 0; j < direction.size(); ++j) {
                // 需要相减,求得前一个坐标
                int prev_x =  x - direction[j][0];
                int prev_y = y - direction[j][1];
                // 非法坐标 
                if (prev_x < 0 || prev_y < 0 || prev_x >= m || prev_y >= n) {
                    continue;
                }
                // 如果前一个坐标点数值,比当前点坐标大,过滤
                if (matrix[prev_x][prev_y] >= matrix[x][y]) {
                    continue;
                }
                // 更新最大路径
                dp[x][y] = max(dp[x][y], dp[prev_x][prev_y]+1);
            }
            
        }
        int result = 1;
        for (int i = 0; i < m; ++i) {
            for (int j = 0; j < n; ++j) {
                // 每一个位置都有可能是最长路径
                result = max(result, dp[i][j]);
            }
        }
        return result;
    }
};// 九章算法强化班版本:
public class Solution {
    /**
     * @param matrix: A 2D-array of integers
     * @return: an integer
     */
    int[][] dp;
    int n, m;
    public int longestContinuousIncreasingSubsequence2(int[][] A) {
        if (A.length == 0) {
            return 0;
        }
        n = A.length;
        m = A[0].length;
        int ans = 0;
        dp = new int[n][m]; // dp[i][j] means the longest continuous increasing path from (i,j)
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < m; ++j) {
                dp[i][j] = -1; // dp[i][j] has not been calculated yet
            }
        }
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < m; ++j) {
                search(i, j, A);
                ans = Math.max(ans, dp[i][j]);
            }
        }
        return ans;
    }
    int[] dx = { 1, -1, 0, 0 };
    int[] dy = { 0, 0, 1, -1 };
    void search(int x, int y, int[][] A) {
        if (dp[x][y] != -1) { // if dp[i][j] has been calculated, return directly
            return;
        }
        int nx, ny;
        dp[x][y] = 1;
        for (int i = 0; i < 4; ++i) {
            nx = x + dx[i];
            ny = y + dy[i];
            if (nx >= 0 && nx < n && ny >= 0 && ny < m) {
                if (A[nx][ny] > A[x][y]) {
                    search(nx, ny, A); // dp[nx][ny] must be calcuted
                    dp[x][y] = Math.max(dp[x][y], dp[nx][ny] + 1);
                }
            }
        }
    }
}


















