一、题目描述
二、算法思路
这是⼀道非常典型的「搜索」类问题。
我们可以通过「深搜」或者「宽搜」,从 [0, 0] 点出发,按照题目的要求(选择 向右移动一格 或 向下移动一格,但不能移动到衣柜之外 )一直往 [m - 1, n - 1] 位置走。
同时,设置⼀个全局变量。每次走到⼀个合法位置,就将全局变量加一。当我们把所有能走到的路都走 完之后,全局变量里面存的就是最终答案。
三、解法
在这里我们使用的是floodfill算法。
题目要求是选择 向右移动一格 或 向下移动一格,但不能移动到衣柜之外。对此,我们可以创建dx,dy两个移动数组,dx中的值表示当前行要加的数,dy中的值表示当前列要加的数。
令dx = {0,1}; dy = {1,0},必须保证dx数组中的0对应dy数组中的1,dy数组中的1对应dy数组中的0。这样才能实现向右移动和向下移动。
我们举例来说明一下:
假设当前处于二维数组中下标为[1,2]的位置,
我们向右移动,则到达[1,3]。向右移动时,行不变,只需列+1;
向下移动,则到达[2,2]。向下移动时,列不变,只需行+1;
我们还要创建一个布尔类型的标记数组vis,将遍历过的位置标记一下,避免重复遍历。
递归函数:对于本题,我们的递归函数dfs,参数只需当前下标位置(int i ,int j)。
解决该题,我们还需要一个验证数位之和是否满足题目要求的函数。
四、解题代码
class Solution {int m, n;int[] dx = {0,1};int[] dy = {1,0};boolean[][] vis;int cnt;int ret; //统计结果public int wardrobeFinishing(int _m, int _n, int _cnt) {m = _m;n = _n;cnt = _cnt;vis = new boolean[m][n];dfs(0,0); return ret;}public void dfs(int i, int j) {ret++;vis[i][j] = true;//遍历dx,dy,相当于遍历向右、向下的位置for(int k = 0; k < 2; k++) {int x = i + dx[k];int y = j + dy[k];if(x >= 0 && x < m && y >= 0 && y < n && !vis[x][y] && check(x,y)) {dfs(x,y);}}}public boolean check(int i, int j) {int tmp = 0;while(i != 0) {tmp += i % 10;i /= 10;}while(j != 0) {tmp += j % 10;j /= 10;}return tmp <= cnt;}
}