链接: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);
}
}
}
}
}