二维矩阵的深度优先搜索

Leetcode 例题:
    1. 岛屿数量 https://leetcode-cn.com/problems/number-of-islands/
    1. 单词搜索 https://leetcode-cn.com/problems/word-search/
注意与技巧
  • 控制遍历方向(向左右上下),可以使用数组,
vector<pair<int, int>> dir = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};

注意 dir 如果换成 vector<vector<int>>类型,那内存消耗和运行时间会增加数倍。

  • 深度优先搜索与回溯算法原理相同,都以递归为核心。
200. 岛屿数量
class Solution {
public:
    void dfs(vector<vector<char>>& grid, int r, int c) {
        int n = grid.size();
        int m = grid.at(0).size();
        grid[r][c] = '0';
        if(r-1>=0 && grid[r-1][c]=='1') dfs(grid, r-1, c); 
        if(r+1<n && grid[r+1][c]=='1') dfs(grid, r+1, c); 
        if(c-1>=0 && grid[r][c-1]=='1') dfs(grid, r, c-1); 
        if(c+1<m && grid[r][c+1]=='1') dfs(grid, r, c+1); 
    }

    int numIslands(vector<vector<char>>& grid) {
        int ans = 0;
        int n = grid.size();
        if (n==0) return 0;
        int m = grid.at(0).size();
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if (grid[i][j]=='1') {
                    ans++;
                    dfs(grid, i, j);
                }
            }
        }
        return ans;
    }
};
79. 单词搜索
class Solution {
public:
    int n, m;
    bool exist(vector<vector<char>>& board, string word) {
        n = board.size();
        m = board[0].size();
        vector<vector<int>> visited(n, vector<int>(m)); // 默认全0,int默认初始化为0
        for(int i = 0; i < n; ++i) {
            for (int j = 0; j < m; ++j) {
                if(dfs(board, visited, word, i, j, 0)) return true;
            }
        }
        return false;
    }

    // bd 目标矩阵
    // vis 标示矩阵中的元素是否访问过
    // word 目标单词
    // i,j 从 bd[i][j]开始搜索
    // 从bd[i][j]为起点开始搜索 单词 word.substr(k, word.size()-k+1),即word以下标k开始的单词
    bool dfs(vector<vector<char>> &bd, vector<vector<int>> &vis, string& word, int i, int j, int k) {
        if (bd[i][j] != word[k]) return false;
        if (k == word.size()-1) return true;
        vis[i][j] = 1;
        // 注意 dir 如果换成 vector<vector<int>>类型,那内存消耗和运行时间会增加数倍
        vector<pair<int, int>> dir = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
        
        bool res = false;
        for (auto &d : dir) {
            int newi = i + d.first, newj = j + d.second;
            if(newi >= 0 && newi < n && newj >= 0 && newj < m) {
                bool tmp = false;
                if(!vis[newi][newj]) 
                    tmp = dfs(bd, vis, word, newi, newj, k+1);
                if(tmp) {
                    res = true;
                    break;
                }
            }
        }
        vis[i][j] = 0;
        return res;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值