给定一个二维矩阵,找出最长的递减序列
Find longest sequence of decreasing numbers given a 2D matrix
给定一个二维数组,找到递减数字的最长序列。约束是:
1.不能对角比较元素
例如:
56 14 51 58 88
26 94 24 39 41
24 16 8 51 51
76 72 77 43 10
38 50 59 84 81
5 23 37 71 77
96 10 93 53 82
94 15 96 69 9
74 0 62 38 96
37 54 55 82 38
这里的答案是:7
下面的矩阵
1 2 3 4 5
16 17 18 19 6
15 24 25 20 7
14 23 22 21 8
13 12 11 10 9
答案是 25,因为我可以时尚移动 25 -> 24 -> 23 -> 22 -> ....等等......直到我达到 1.
谁能帮我算算法。
这是我的初始代码:
int dx[4] = {0, 1, -1, 0};
int dy[4] = {1, 0, 0, -1};
int findSequence(int x, int y)
{
for(int i = 0; i < 4; ++i)
{
int new_x = x + dx[i];
int new_y = y + dy[i];
if(isValid(new_x, new_y) && data[x][y] > data[new_x][new_y])
{
std::cout << "" << data[x][y] << " -> " << data[new_x][new_y] << " ";
int tmp = 1 + findSequence(new_x, new_y, isVisited);
//std::cout << " "<< tmp << " ";
return tmp;
}
}
}
谢谢
我建议您按降序访问这些数字。
将矩阵初始化为全零。该矩阵将代表在此点结束的最长序列。
现在遍历矩阵中的所有位置(按原始矩阵中值递减的顺序)。对于每个位置,将矩阵中的值设置为 1 + 任何相邻位置中的最大值。
在您访问完所有位置后,矩阵中的最大值将是您问题的解决方案。
你可以使用递归。假设我们想要从索引 (i,j)
开始获得最大序列。然后我们可以在第 4 个方向的任何方向移动 (i1,j1)
如果 A[i][j] > A[i1][j1]
其中 A 是二维数组。
const int N=50;
int A[N][N];
int res=0; // maximum result
int calc(int i, int j) {
int r=1; // only this element forms a single element sequence
if(A[i][j]>A[i][j+1]) r=max(r, 1+ calc(i, j+1));
if(A[i][j]>A[i][j-1]) r=max(r, 1+ calc(i, j-1));
if(A[i][j]>A[i+1][j]) r=max(r, 1+ calc(i+1, j));
if(A[i][j]>A[i-1][j]) r=max(r, 1+ calc(i-1, j));
res=max(res,r);
return r;
}
复杂度:O(mn) 如果结果存储在二维数组中,其中 m 是行数和 n 列数。
这是带有记忆的代码。
class Solution {
int[] xdir = new int[]{-1,1,0,0};
int[] ydir = new int[]{0,0,-1,1};
public boolean isValid(int i, int j, int m, int n){
if(i < 0 || j < 0 || i >= m || j >=n)return false;
return true;
}
public int dfs(int i, int j, int[][] mat, int[][]memo, int m, int n){
if(memo[i][j] != 0)return memo[i][j];
int mx = 1;
for(int k = 0; k < 4; k++){
int ni = i + xdir[k];
int nj = j + ydir[k];
if(isValid(ni, nj, m, n) && mat[ni][nj] < mat[i][j]){
mx = Math.max(mx, 1 + dfs(ni, nj, mat, memo, m, n));
}
}
memo[i][j] = mx;
return mx;
}
public int longestDecreasingPath(int[][] mat) {
int m = mat.length;
int n = mat[0].length;
int[][] memo = new int[m][n];
int ans = 0;
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
if(memo[i][j] == 0){
ans = Math.max(ans, dfs(i, j, mat, memo, m, n));
}
}
}
return ans;
}
}
给定一个二维数组,找到递减数字的最长序列。约束是: 1.不能对角比较元素
例如:
56 14 51 58 88
26 94 24 39 41
24 16 8 51 51
76 72 77 43 10
38 50 59 84 81
5 23 37 71 77
96 10 93 53 82
94 15 96 69 9
74 0 62 38 96
37 54 55 82 38
这里的答案是:7
下面的矩阵
1 2 3 4 5
16 17 18 19 6
15 24 25 20 7
14 23 22 21 8
13 12 11 10 9
答案是 25,因为我可以时尚移动 25 -> 24 -> 23 -> 22 -> ....等等......直到我达到 1.
谁能帮我算算法。
这是我的初始代码:
int dx[4] = {0, 1, -1, 0};
int dy[4] = {1, 0, 0, -1};
int findSequence(int x, int y)
{
for(int i = 0; i < 4; ++i)
{
int new_x = x + dx[i];
int new_y = y + dy[i];
if(isValid(new_x, new_y) && data[x][y] > data[new_x][new_y])
{
std::cout << "" << data[x][y] << " -> " << data[new_x][new_y] << " ";
int tmp = 1 + findSequence(new_x, new_y, isVisited);
//std::cout << " "<< tmp << " ";
return tmp;
}
}
}
谢谢
我建议您按降序访问这些数字。
将矩阵初始化为全零。该矩阵将代表在此点结束的最长序列。
现在遍历矩阵中的所有位置(按原始矩阵中值递减的顺序)。对于每个位置,将矩阵中的值设置为 1 + 任何相邻位置中的最大值。
在您访问完所有位置后,矩阵中的最大值将是您问题的解决方案。
你可以使用递归。假设我们想要从索引 (i,j)
开始获得最大序列。然后我们可以在第 4 个方向的任何方向移动 (i1,j1)
如果 A[i][j] > A[i1][j1]
其中 A 是二维数组。
const int N=50;
int A[N][N];
int res=0; // maximum result
int calc(int i, int j) {
int r=1; // only this element forms a single element sequence
if(A[i][j]>A[i][j+1]) r=max(r, 1+ calc(i, j+1));
if(A[i][j]>A[i][j-1]) r=max(r, 1+ calc(i, j-1));
if(A[i][j]>A[i+1][j]) r=max(r, 1+ calc(i+1, j));
if(A[i][j]>A[i-1][j]) r=max(r, 1+ calc(i-1, j));
res=max(res,r);
return r;
}
复杂度:O(mn) 如果结果存储在二维数组中,其中 m 是行数和 n 列数。
这是带有记忆的代码。
class Solution {
int[] xdir = new int[]{-1,1,0,0};
int[] ydir = new int[]{0,0,-1,1};
public boolean isValid(int i, int j, int m, int n){
if(i < 0 || j < 0 || i >= m || j >=n)return false;
return true;
}
public int dfs(int i, int j, int[][] mat, int[][]memo, int m, int n){
if(memo[i][j] != 0)return memo[i][j];
int mx = 1;
for(int k = 0; k < 4; k++){
int ni = i + xdir[k];
int nj = j + ydir[k];
if(isValid(ni, nj, m, n) && mat[ni][nj] < mat[i][j]){
mx = Math.max(mx, 1 + dfs(ni, nj, mat, memo, m, n));
}
}
memo[i][j] = mx;
return mx;
}
public int longestDecreasingPath(int[][] mat) {
int m = mat.length;
int n = mat[0].length;
int[][] memo = new int[m][n];
int ans = 0;
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
if(memo[i][j] == 0){
ans = Math.max(ans, dfs(i, j, mat, memo, m, n));
}
}
}
return ans;
}
}