机器人的运动范围和岛问题
剑指Offer上面的 机器人的运动范围 和 岛问题 有着相似的解题思路。都可以通过矩阵的深度优先查询来解决这两个问题。
机器人的运动范围
题目
地上有一个m行n列的方格,从坐标 [0,0] 到坐标 [m-1,n-1] 。一个机器人从坐标 [0, 0] 的格子开始移动,它每次可以向左、右、上、下移动一格(不能移动到方格外),也不能进入行坐标和列坐标的数位之和大于k的格子。例如,当k为18时,机器人能够进入方格 [35, 37] ,因为3+5+3+7=18。但它不能进入方格 [35, 38],因为3+5+3+8=19。请问该机器人能够到达多少个格子?
示例 1:
输入:m = 2, n = 3, k = 1 输出:3
示例 2:
输入:m = 3, n = 1, k = 0 输出:1
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/ji-qi-ren-de-yun-dong-fan-wei-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
public int movingCount(int m, int n, int k) {
if (m == 0 || n == 0){
return 0 ;
}
int[][] dp = new int[m][n] ;
int result = process(0 , 0 , m-1 , n-1 , k , dp) ;
return result ;
}
//能进入的一定是合法的
private int process(int i , int j , int m , int n , int k , int[][] dp){
boolean flag = isUsable(i , j , k) ;
//首先判断当前位置是否可用
if (!flag || dp[i][j] == 1){
//当前位置不可用 - 不可用的两个条件:当前位置不合法;或者已经遍历过了
//当前位置不合法,设置为1
dp[i][j] = 1 ;
return 0 ;
}
//将当前位置设置为1,也就是递归过
dp[i][j] = 1 ;
//当前位置符合条件,所以count = 1
int count = 1 ;
//这么if 是为了更好的展现思路
if (i > 0){
//上
count += process(i-1 , j , m , n , k , dp) ;
}
if (i < m){
//下
count += process(i+1 , j , m , n , k , dp) ;
}
if (j > 0){
//左
count += process(i , j-1 , m , n , k , dp) ;
}
if (j < n){
//右
count += process(i , j+1 , m , n , k , dp) ;
}
return count ;
}
//判断i和j的各位相加是否大于k
private boolean isUsable(int i, int j, int k) {
return addEveryIndex(i) + addEveryIndex(j) <= k ;
}
//计算一个数的所有位数和
private int addEveryIndex(int num){
int count = 0 ;
int x = 1 ;
while(num != 0){
x = x * 10 ;
count += num % x ;
num = num / 10 ;
}
return count ;
}
岛问题
标注:这是左神写的代码,这个是求解岛的数量问题。同时岛问题也可以采用并查集做。
题目
给你一个由
'1'
(陆地)和'0'
(水)组成的的二维网格,请你计算网格中岛屿的数量。
public int countIslands(int[][] m) {
if (m == null || m[0] == null) {
return 0;
}
int N = m.length;
int M = m[0].length;
int res = 0;
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
if (m[i][j] == 1) {
res++;
infect(m, i, j, N, M);
}
}
}
return res;
}
public void infect(int[][] m, int i, int j, int N, int M) {
//设定范围
if (i < 0 || i >= N || j < 0 || j >= M || m[i][j] != 1) {
return;
}
//遍历过的岛改状态值为2
m[i][j] = 2;
//上下左右四个方向
infect(m, i + 1, j, N, M);
infect(m, i - 1, j, N, M);
infect(m, i, j + 1, N, M);
infect(m, i, j - 1, N, M);
}