数据结构与算法——搜索

数据结构与算法——广度搜索BFS

例1:岛屿数量(medium)(深搜、宽搜)

在这里插入图片描述

class Solution {
private:
 void dfs(vector<vector<char>>& grid, int r, int c) {
  int nr = grid.size();
  int nc = grid[0].size();
  grid[r][c] = '0';
  if (r - 1 >= 0 && grid[r - 1][c] == '1') dfs(grid, r - 1, c);
  if (r + 1 < nr && 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 < nc && grid[r][c + 1] == '1') dfs(grid, r, c + 1);
 }
public:
 int numIslands(vector<vector<char>>& grid) {
  int nr = grid.size();
  if (!nr) return 0;
  int nc = grid[0].size();
  int num_islands = 0;
  for (int r = 0; r < nr; r++) {
   for (int c = 0; c < nc; c++) {
    if (grid[r][c] == '1') {
     num_islands++;
     dfs(grid, r, c);
    }
   }
  }
  return num_islands;
 }
};
class Solution:
    def dfs(self, grid, r, c):
        grid[r][c] = 0
        nr, nc = len(grid), len(grid[0])
        for x, y in [(r - 1, c), (r + 1, c), (r, c - 1), (r, c + 1)]:
            if 0 <= x < nr and 0 <= y < nc and grid[x][y] == "1":
                self.dfs(grid, x, y)

    def numIslands(self, grid: List[List[str]]) -> int:
        nr = len(grid)
        if nr == 0:
            return 0
        nc = len(grid[0])
        num_islands = 0
        for r in range(nr):
            for c in range(nc):
                if grid[r][c] == "1":
                    num_islands += 1
                    self.dfs(grid, r, c)

        return num_islands

BFS:

import collections

class Solution2():
    def __init__(self) -> None:
        self.dx=[-1,1,0,0]
        self.dy=[0,0,-1,1]

    def bfs(self,grid,q,x,y):
        grid[x][y]=0
        q.append((x,y))
        r, c = len(grid), len(grid[0])
        while q:
            x,y=q.popleft()
            for i in range(4):
                new_x,new_y=x+self.dx[i],y+self.dy[i]
                if 0<=new_x<r and 0<=new_y<c:
                    if grid[new_x][new_y]==1:
                        q.append((new_x,new_y))
                        grid[new_x][new_y]=0
                        # self.print_1(grid)

    def numIslands(self,grid):
        num_islands=0
        r, c = len(grid), len(grid[0])
        q = collections.deque()
        for i in range(r):
            for j in range(c):
                if grid[i][j]==1:
                    self.bfs(grid,q,i,j)
                    num_islands+=1
        return num_islands


    def print_1(self,grid):
        for i in range(len(grid)):
            print(grid[i])
        print("_________________")

例2:词语阶梯(medium)(宽搜、图、哈希表)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

class Solution {
public:
 //用于判断
 bool connect(const string& word1, const string& word2) {
  int cnt = 0;//记录word1与word2不相等的数量
  for (int i = 0; i < word1.length(); i++) {
   if (word1[i] != word2[i]) {
    cnt++;
   }
  }
  return cnt == 1;
 }
 //构建图
 void construct_graph(string& beginWord, vector<string>& wordList, map<string, vector<string>>& graph) {
  wordList.push_back(beginWord);
  for (int i = 0; i < wordList.size(); i++) {
   graph[wordList[i]] = vector<string>();
  }
  for (int i = 0; i < wordList.size(); i++) {
   for (int j = i + 1; j < wordList.size(); j++) {
    if (connect(wordList[i], wordList[j])) {
     graph[wordList[i]].push_back(wordList[j]);
     graph[wordList[j]].push_back(wordList[i]);
    }
   }
  }
 }
 //图的宽搜
 int BFS_graph(string& beginWord, string& endWord, map<string, vector<string>>& graph) {
  queue<pair<string, int>>Q;
  set<string>visit;
  Q.push(make_pair(beginWord, 1));
  visit.insert(beginWord);
  while (!Q.empty()) {
   string node = Q.front().first;
   int step = Q.front().second;
   Q.pop();
   if (node == endWord) {
    return step;
   }
   const vector<string>& neighbors = graph[node];
   for (int i = 0; i < neighbors.size(); i++) {
    if (visit.find(neighbors[i]) == visit.end()) {
     Q.push(make_pair(neighbors[i], step + 1));
     visit.insert(neighbors[i]);
    }
   }
  }
  return 0;
 }
 int ladderLength(string beginWord, string endWord, vector<string>& wordList) {
  map<string, vector<string>>graph;
  construct_graph(beginWord, wordList, graph);
  return BFS_graph(beginWord, endWord, graph);
 }
};

例3:火柴棍摆正方形(medium)(回溯深搜、位运算)

在这里插入图片描述
在这里插入图片描述

class Solution {
public:
 bool makesquare(vector<int>& matchsticks) {
  if (matchsticks.size() < 4) {
   return false;
  }
  int sum = 0;
  for (int i = 0; i < matchsticks.size(); i++) {
   sum += matchsticks[i];
  }
  if (sum % 4) {
   return false;
  }
  sort(matchsticks.rbegin(), matchsticks.rend());
  int bucket[4] = { 0 };
  return generate(0, matchsticks, sum / 4, bucket);
 }
private:
 bool generate(int i, vector<int>& matchsticks, int target, int bucket[]) {
  if (i >= matchsticks.size()) {
   return bucket[0] == target && bucket[1] == target && bucket[2] == target && bucket[3] == target;
  }
  for (int j = 0; j < 4; j++) {
   if (bucket[j] + matchsticks[i] > target) {
    continue;
   }
   bucket[j] += matchsticks[i];
   if (generate(i + 1, matchsticks, target, bucket)) {
    return true;
   }
   bucket[j] -= matchsticks[i];
  }
  return false;
 }
};
class Solution:
    def generate(self,i,match_list,target,one_list):
        if i>=len(match_list):
            if one_list[0]==target and one_list[1]==target and one_list[2]==target and one_list[3]==target:
                return True
        for j in range(4):
            if one_list[j]+match_list[i]>target:
                continue
            one_list[j]+=match_list[i]
            if self.generate(i+1,match_list,target,one_list):
                return True
            one_list[j]-=match_list[i]
        return False

    def makesquare(self,match_list,target):
        if len(match_list)<4:
            return False
        sum_len=sum(match_list)
        if sum_len%4 !=0:
            return False
        match_list.sort(reverse=True)
        print(match_list)
        one_list=[0,0,0,0]
        return(self.generate(0,match_list,target,one_list))

例4:收集雨水2(hard)(带优先级的宽度优先搜索、堆)

在这里插入图片描述

struct B {
 int h;
 int x;
 int y;
 B(int hh, int xx, int yy) {
  h = hh;
  x = xx;
  y = yy;
 }
};

struct CompareHeight {
 bool operator()(B const& b1, B const& b2) {
  return b1.h > b2.h;
 }
};

class Solution {
public:
 int trapRainWater(vector<vector<int>>& heightMap) {
  priority_queue<B, vector<B>, CompareHeight> q;
  int ans = 0;
  int m = heightMap.size();
  int n = heightMap[0].size();
  vector<vector<bool>> vis = vector<vector<bool>>(m, vector<bool>(n, false));
  if (m < 3 || n < 3) return 0;
  for (int i = 0; i < m; i++) {
   q.push(B(heightMap[i][0], i, 0));
   q.push(B(heightMap[i][n - 1], i, n - 1));
   vis[i][0] = true;
   vis[i][n - 1] = true;
  }
  for (int j = 0; j < n; j++) {
   q.push(B(heightMap[0][j], 0, j));
   q.push(B(heightMap[m - 1][j], m - 1, j));
   vis[0][j] = true;
   vis[m - 1][j] = true;
  }
  int dx[4] = { 1,-1,0,0 };
  int dy[4] = { 0,0,1,-1 };
  while (!q.empty()) {
   B b = q.top();
   q.pop();
   int x = b.x;
   int y = b.y;
   int h = b.h;
   for (int d = 0; d < 4; d++) {
    int xx = x + dx[d];
    int yy = y + dy[d];
    if (xx < 0 || xx >= m || yy < 0 || yy >= n) continue;
    if (vis[xx][yy]) continue;
    vis[xx][yy] = true;
    int height = heightMap[xx][yy];
    if (height <= h) {
     ans += h - height;
     q.push(B(h, xx, yy));
    }
    else {
     q.push(B(height, xx, yy));
    }
   }
  }
  return ans;
 }
};

例5:529. 扫雷游戏(medium)DFS、BFS

在这里插入图片描述

#Dfs
class Solution1:
    def updateBoard(self, board, click):
        i, j = click
        row, col = len(board), len(board[0])
        if board[i][j] == "M":
            board[i][j] = "X"
            return board

        # 计算空白快周围的***
        def cal(i, j):
            res = 0
            for x in [1, -1, 0]:
                for y in [1, -1, 0]:
                    if x == 0 and y == 0: continue
                    if 0 <= i + x < row and 0 <= j + y < col and board[i + x][j + y] == "M": res += 1
            return res

        def dfs(i, j):
            num = cal(i, j)
            if num > 0:
                board[i][j] = str(num)
                # print(i,j,": ")
                # for i in range(len(board)):
                #     print(board[i])
                return
            board[i][j] = "B"
            # print(i, j, ": ")
            # for a in range(len(board)):
            #     print(board[a])
            for x in [-1, 1, 0]:
                for y in [-1, 1, 0]:
                    #自身跳过
                    if x == 0 and y == 0: continue
                    nxt_i, nxt_j = i + x, j + y
                    if 0 <= nxt_i < row and 0 <= nxt_j < col and board[nxt_i][nxt_j] == "E": dfs(nxt_i, nxt_j)

        dfs(i, j)
        return board
#BFS
class Solution:
    def updateBoard(self, board, click) :
        i, j = click
        row, col = len(board), len(board[0])
        if board[i][j] == "M":
            board[i][j] = "X"
            return board

        # 计算空白快周围的***
        def cal(i, j):
            res = 0
            for x in [1, -1, 0]:
                for y in [1, -1, 0]:
                    if x == 0 and y == 0: continue
                    if 0 <= i + x < row and 0 <= j + y < col and board[i + x][j + y] == "M": res += 1
            return res

        def bfs(i, j):
            queue = collections.deque([[i, j]])
            print(queue)
            while queue:
                i, j = queue.pop()
                num = cal(i, j)
                if num > 0:
                    board[i][j] = str(num)
                    continue
                    
                board[i][j] = "B"
                for x in [1, -1, 0]:
                    for y in [1, -1, 0]:
                        if x == 0 and y == 0: continue
                        nxt_i, nxt_j = i + x, j + y
                        if 0 <= nxt_i < row and 0 <= nxt_j < col and board[nxt_i][nxt_j] == "E":
                            queue.appendleft([nxt_i, nxt_j])
                            board[nxt_i][nxt_j] = "B"
        bfs(i, j)
        return board
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小屋*

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值