家居整理师将待整理衣橱划分为 m x n 的二维矩阵 grid,其中 grid[i][j] 代表一个需要整理的格子。整理师自 grid[0][0] 开始 逐行逐列 地整理每个格子。

整理规则为:在整理过程中,可以选择 向右移动一格 或 向下移动一格,但不能移动到衣柜之外。同时,不需要整理 digit(i) + digit(j) > cnt 的格子,其中 digit(x) 表示数字 x 的各数位之和。

请返回整理师 总共需要整理多少个格子

示例 1:

输入:m = 4, n = 7, cnt = 5
输出:18

提示:

  • 1 <= n, m <= 100
  • 0 <= cnt <= 20

思路: DFS

1、定义digit函数,实现数字 x 的各数位之和

2、因为不能重复整理,且题目没有定义二维数组只是给了二维数组的行列,因此我们需要自己定义一个二维数组用来标记哪些格子已经整理过,初始化为符号‘0’。

3、从头([0][0])开始DFS递归遍历

结束条件i、j越界或该元素已经遍历过或digit函数不满足小于等于cnt。
递归工作把该位置为‘1’,表示已经整理,继续向右和向下递归。
返回值返回值为1加上向右和向下递归的结果。

4、注意:采用双层for循环的方法(行优先遍历二维数组所有元素)不可取,因为有一些格子虽然符合条件但是不可达,没有到达他的一条通路。

代码实现:

class Solution {
public:
    int digit(int a)
    {
        int sum = 0;
        while(a)
        {
            sum += a % 10;
            a /= 10;
        }
        return sum;
    }
    int dfs(int i, int j, int m, int n, int cnt,vector<vector<char>>& visited)
    {
        if(i < 0 || j < 0 || i >= m || j>= n || visited[i][j] != '0' || digit(i) + digit(j) > cnt )
            return 0;
        visited[i][j] = '1';
        return 1 + dfs(i + 1, j, m, n, cnt, visited) + dfs(i, j + 1, m, n, cnt, visited);
    }
    int wardrobeFinishing(int m, int n, int cnt) {
        vector<vector<char>> visited(m, vector<char>(n, '0'));
        return dfs(0, 0, m, n, cnt, visited);
    }
};
Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐