剑指Offer-机器人的运动范围

剑指Offer-机器人的运动范围

题目描述

LCR 130. 衣橱整理

家居整理师将待整理衣橱划分为 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

思路描述

计算数位和

int sums(int x){
	int s = 0;
    while(x != 0){
		s = x%10;
        x /= 10;
    }
    return s;
}

这一步比较简单。

DFS

递归
  • 递归参数:当前坐标(i,j),vis引用表(判断是否访问)

  • 递归终止条件:越界或者已访问或者不满足条件(数位和 > cnt)

  • 单层递归逻辑:若不满足终止条件,则将vis标记为已访问

  • 返回:1+ {下节点的递归} + {右节点的递归}

**这里为什么要+1?**是为了,利用回溯的性质,每次递归调用都会使得节点数量+1,也就是返回已访问节点的数量。

代码如下
class Solution {
public:
    int wardrobeFinishing(int m, int n, int cnt) {
        vector<vector<bool>> visited(m,vector<bool>(n,0));// 用于判断是否访问
        return dfs(0,0,m,n,cnt,visited);
    }
     int sums(int x){
        int s = 0;
        while(x != 0){
            s += x%10;
            x /= 10;
        }
        return s;
    }
    int dfs(int i,int j,int m,int n,int cnt,vector<vector<bool>>& vis){
        if(i > m-1 || j >= n ||vis[i][j] ||sums(i)+sums(j) > cnt)return 0;
        vis[i][j] = true;
        return 1+dfs(i+1,j,m,n,cnt,vis)+dfs(i,j+1,m,n,cnt,vis);
    }
   

};

BFS

广度优先思路一样简单,使用队列对节点进行存储。

代码如下:

class Solution {
public:
    int wardrobeFinishing(int m, int n, int cnt) {
        queue<vector<int>> qu;
        vector<vector<bool>> vis(m,vector<bool>(n,0));
        qu.push({0,0});
        int res = 0;
        while(!qu.empty()){
            vector<int> vec = qu.front();qu.pop();
            int i = vec[0],j = vec[1];
            if(i >= m || j >= n || bitsum(i)+bitsum(j) > cnt || vis[i][j])continue;
            
            vis[i][j] = true;
            res++;
            qu.push({i+1,j});
            qu.push({i,j+1});
        }
        return res;
    }
    int bitsum(int x){
        int s = 0;
        while(x!=0){
            s += x%10;
            x /= 10;
        }
        return s;
    }
};

你可能感兴趣的:(算法,算法)