# 二维数组中的递归算法

52 篇文章 4 订阅

### 第一题

##### 题目描述

Michael 喜欢滑雪这并不奇怪， 因为滑雪的确很刺激。可是为了获得速度，滑的区域必须向下倾斜，而且当你滑到坡底，你不得不再次走上坡或者等待升降机来载你。Michael 想知道在一个区域中最长的滑坡。区域由一个二维数组给出，数组的每个数字代表点的高度。下面是一个例子

 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


输入：
5 5
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

##### 题目求解

dfs(i, j) = max{dfs(i-1, j), dfs(i+1, j), dfs(i, j-1), dfs(i, j+1)} + 1。

public class Test {
private static int dfs(int[][] matrix, int i, int j){
int up = 0, down = 0, left = 0, right = 0;
if(i - 1 >= 0 && matrix[i][j] > matrix[i-1][j]) up = dfs(matrix, i-1, j);
if(i + 1 < matrix.length && matrix[i][j] > matrix[i+1][j]) down = dfs(matrix, i+1, j);
if(j - 1 >= 0 && matrix[i][j] > matrix[i][j-1]) left = dfs(matrix, i, j-1);
if(j + 1 < matrix[i].length && matrix[i][j] > matrix[i][j+1]) right = dfs(matrix, i, j+1);
int x, y;
return (x = left>right?left:right) > (y = up>down?up:down) ? x+1 : y+1;
}
public static void main(String[] args) {
int R = 5;
int C = 5;
int[][] matrix = {
{3, 16, 10, 28, 34},
{6, 8, 11, 14, 9},
{20, 1, 54, 27, 15},
{18, 4, 19, 30, 6},
{25, 16, 23, 33, 5}};
int max = 0;
for(int i = 0; i < R; ++i){
for(int j = 0; j < C; ++j){
int temp = dfs(matrix, i, j);
if(temp > max) max = temp;
}
}
System.out.println(max);
}
}


import java.util.Arrays;
public class Test {
private static int dfs(int[][] cache, int[][] matrix, int i, int j){
if(cache[i][j] != 0) return cache[i][j];
int up = 0, down = 0, left = 0, right = 0;
if(i - 1 >= 0 && matrix[i][j] > matrix[i-1][j]){
if(cache[i-1][j] == 0){
up = dfs(cache, matrix, i-1, j);
cache[i-1][j] = up;
}else up = cache[i-1][j];
}
if(i + 1 < matrix.length && matrix[i][j] > matrix[i+1][j]){
if(cache[i+1][j] == 0){
down = dfs(cache, matrix, i+1, j);
cache[i+1][j] = down;
}else down = cache[i+1][j];
}
if(j - 1 >= 0 && matrix[i][j] > matrix[i][j-1]){
if(cache[i][j-1] == 0){
left = dfs(cache, matrix, i, j-1);
cache[i][j-1] = left;
}else left = cache[i][j-1];
}
if(j + 1 < matrix[i].length && matrix[i][j] > matrix[i][j+1]){
if(cache[i][j+1] == 0){
right = dfs(cache, matrix, i, j+1);
cache[i][j+1] = right;
}else right = cache[i][j+1];
}
int x, y;
cache[i][j] = (x = left>right ? left : right) > (y = up>down ? up : down) ? x+1 : y+1;
return cache[i][j];
}
public static void main(String[] args) {
int R = 5;
int C = 5;
int[][] matrix = {
{3, 16, 10, 28, 34},
{6, 8, 11, 14, 9},
{20, 1, 54, 27, 15},
{18, 4, 19, 30, 6},
{25, 16, 23, 33, 5}};
int[][] cache = new int[R][C];
int max = 0;
for(int i = 0; i < R; ++i){
for(int j = 0; j < C; ++j){
int temp = dfs(cache, matrix, i, j);
if(temp > max) max = temp;
}
}
System.out.println(Arrays.deepToString(cache));
System.out.println(max);
}
}


import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

class Index implements Comparable<Index>{ // 定义存放数组值以及对应下标的可比较类
int i, j, value;
public Index(int i, int j, int value) {
this.i = i;
this.j = j;
this.value = value;
}
@Override
public int compareTo(Index o) {
return value-o.value;
}
}
public class Test {
// 按照 matrix 数组中值从小到大的顺序，处理 cache 数组
private static int pathLength(List<Index> indexs, int [][] cache, int r, int c){
int max = 0;
for(Index e : indexs){
int i = e.i, j = e.j;
int up = 0, down = 0, left = 0, right = 0;
if(i-1 >= 0) up = cache[i-1][j];
if(i+1 < r) down = cache[i+1][j];
if(j-1 >= 0) left = cache[i][j-1];
if(j+1 < c) right = cache[i][j+1];
int x, y;
cache[i][j] = (x = left>right?left:right) > (y = up>down?up:down) ? x+1 : y+1;
if(cache[i][j] > max) max = cache[i][j];
}
return max;
}
public static void main(String[] args) {
int R = 5;
int C = 5;
int[][] matrix = {
{3, 16, 10, 28, 34},
{6, 8, 11, 14, 9},
{20, 1, 54, 27, 15},
{18, 4, 19, 30, 6},
{25, 16, 23, 33, 5}};
List<Index> indexs = new ArrayList<>();
for(int i = 0; i < R; ++i){
for(int j = 0; j < C; ++j){
}
}
Collections.sort(indexs);
int[][] cache = new int[R][C];
System.out.println(pathLength(indexs, cache, R, C));
}
}


### 第二题

##### 题目描述

1 <= N <= 500
1 <= M <= 500
0 <= K <= 10

输入：
3	3	1
1	3	3
2	4	9
8	9	2

6

##### 题目求解

public class Test {
private static int dfs(int[][] matrix, int k, int i, int j){
int up = 0, down = 0, left = 0, right = 0;
if(i-1 >= 0){
int up0 = 0, up1 = 0;
if(matrix[i][j] < matrix[i-1][j]){
up0 = dfs(matrix, k, i-1, j);
}else if(k > 0){
up1 = dfs(matrix, k-1, i-1, j);
}
up = up0>up1 ? up0 : up1;
}
if(i+1 <= matrix.length-1){
int down0 = 0, down1 = 0;
if(matrix[i][j] < matrix[i+1][j]){
down0 = dfs(matrix, k, i+1, j);
}else if(k > 0){
down1 = dfs(matrix, k-1, i+1, j);
}
down = down0>down1 ? down0 : down1;
}
if(j-1 >= 0){
int left0 = 0, left1 = 0;
if(matrix[i][j] < matrix[i][j-1]){
left0 = dfs(matrix, k, i, j-1);
}else if(k > 0){
left1 = dfs(matrix, k-1, i, j-1);
}
left = left0>left1 ? left0 : left1;
}
if(j+1 <= matrix[i].length-1){
int right0 = 0, right1 = 0;
if(matrix[i][j] < matrix[i][j+1]){
right0 = dfs(matrix, k, i, j+1);
}else if(k > 0){
right1 = dfs(matrix, k-1, i, j+1);
}
right = right0>right1 ? right0 : right1;
}
int x, y;
return (x = right>left?right:left) > (y = up>down?up:down) ? x+1 : y+1;
}
public static void main(String[] args) {
int N = 3;
int M = 3;
int K = 1;
int[][] matrix = {{1,3,3},{2,4,9},{8,9,2}};
int max = 0;
for(int i = 0; i < N; ++i){
for(int j = 0; j < M; ++j){
int temp = dfs(matrix, K, i, j);
if(temp > max) max = temp;
}
}
System.out.println(max);
}
}


import java.util.Arrays;
public class Test {
private static int dfs(int[][][] cache, int[][] matrix, int k, int i, int j){
if(cache[k][i][j] != 0) return cache[k][i][j];
int up = 0, down = 0, left = 0, right = 0;
if(i-1 >= 0){
int up0 = 0, up1 = 0;
if(matrix[i][j] < matrix[i-1][j]){
if(cache[k][i-1][j] == 0){
up0 = dfs(cache, matrix, k, i-1, j);
cache[k][i-1][j] = up0;
}else up0 = cache[k][i-1][j];
}else if(k > 0){
if(cache[k-1][i-1][j] == 0){
up1 = dfs(cache, matrix, k-1, i-1, j);
cache[k-1][i-1][j] = up1;
}else up1 = cache[k-1][i-1][j];
}
up = up0>up1 ? up0 : up1;
}
if(i+1 <= matrix.length-1){
int down0 = 0, down1 = 0;
if(matrix[i][j] < matrix[i+1][j]){
if(cache[k][i+1][j] == 0){
down0 = dfs(cache, matrix, k, i+1, j);
cache[k][i+1][j] = down0;
}else down0 = cache[k][i+1][j];
}else if(k > 0){
if(cache[k-1][i+1][j] == 0){
down1 = dfs(cache, matrix, k-1, i+1, j);
cache[k-1][i+1][j] = down1;
}else down1 = cache[k-1][i+1][j];
}
down = down0>down1 ? down0 : down1;
}
if(j-1 >= 0){
int left0 = 0, left1 = 0;
if(matrix[i][j] < matrix[i][j-1]){
if(cache[k][i][j-1] == 0){
left0 = dfs(cache, matrix, k, i, j-1);
cache[k][i][j-1] = left0;
}else left0 = cache[k][i][j-1];
}else if(k > 0){
if(cache[k-1][i][j-1] == 0){
left1 = dfs(cache, matrix, k-1, i, j-1);
cache[k-1][i][j-1] = left1;
}else left1 = cache[k-1][i][j-1];
}
left = left0>left1 ? left0 : left1;
}
if(j+1 <= matrix[i].length-1){
int right0 = 0, right1 = 0;
if(matrix[i][j] < matrix[i][j+1]){
if(cache[k][i][j+1] == 0){
right0 = dfs(cache, matrix, k, i, j+1);
cache[k][i][j+1] = right0;
}else right0 = cache[k][i][j+1];
}else if(k > 0){
if(cache[k-1][i][j+1] == 0){
right1 = dfs(cache, matrix, k-1, i, j+1);
cache[k-1][i][j+1] = right1;
}else right1 = cache[k-1][i][j+1];
}
right = right0>right1 ? right0 : right1;
}
int x, y;
cache[k][i][j] = (x = right>left ? right : left) > (y = up>down ? up : down) ? x+1 : y+1;
return cache[k][i][j];
}
public static void main(String[] args) {
int N = 3;
int M = 3;
int K = 1;
int[][] matrix = {{1,3,3},{2,4,9},{8,9,2}};
int[][][] cache = new int[k+1][N][M];
int max = 0;
for(int i = 0; i < N; ++i){
for(int j = 0; j < M; ++j){
int temp = dfs(cache, matrix, K, i, j);
if(temp > max) max = temp;
}
}
System.out.println(Arrays.deepToString(cache));
System.out.println(max);
}
}


### 总结

• 2
点赞
• 3
收藏
觉得还不错? 一键收藏
• 0
评论
12-22 1349
04-12 567
04-10 1723
09-29 1614
07-05 1294
04-09
11-25 829
12-10 503
04-09 518
07-20 2175
10-06 238
11-08 299

1.余额是钱包充值的虚拟货币，按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载，可以购买VIP、付费专栏及课程。