Leetcode 刷题笔记 (搜索)

Leetcode 刷题笔记 (搜索)

idea

  1. dfs 递归
  2. dfs + 栈
  3. bfs
  4. 拓扑排序

dfs模板

#dfs 模板
notice:
1. 判定进入dfs的条件是什么
2. 判定dfs循环内要访问什么
3. 要进入主循环!!!!!!!!
move = [[1,0],[-1,0],[0,1],[0,-1]]

#主循环
for i in range(i): #行

    for j in range(j):#列
        if 判定条件:
            dfs(i,j)

def dfs(i,j,visited):
    #1.
    if i < 0 or j < 0 or i == len(grid) or j == len(grid[0]) or grid[i][j] == 0:
        return 0  # 找1
    #2.
    if visited[i][j] == 1: #已经访问跳过
        reuturn
    visited[i][j] = 1 #访问后为1
    for di,dj in move:
        next_i = di + i
        next_j = dj + j
        #判断越界
        if width > next_i >= 0 and lenth > next_j >= 0 and ...
              dfs(next_i,next_j,visited)

695. 岛屿的最大面积(medium)

https://leetcode-cn.com/problems/max-area-of-island/

dfs 递归

class Solution:
    def dfs(self, grid, cur_i, cur_j):
        if cur_j<0 or cur_i<0 or cur_i == len(grid) or cur_j == len(grid[0]) or grid[cur_i][cur_j] == 0:
            return 0
        move = [[1,0],[-1,0],[0,1],[0,-1]]
        grid[cur_i][cur_j] = 0
        ans = 1
        for d_i, d_j in move:
            next_i = d_i + cur_i
            next_j = d_j + cur_j
            ans += self.dfs(grid,next_i,next_j)
        return ans
    def maxAreaOfIsland(self, grid: List[List[int]]) -> int:
        ans = 0
        for row,val in enumerate(grid):
            for column, _ in enumerate(val):
                ans = max(ans, self.dfs(grid, row, column))
        return ans

dfs 栈

class Solution:
    def maxAreaOfIsland(self, grid: List[List[int]]) -> int:
        ans = 0
        move = [[1,0],[-1,0],[0,1],[0,-1]]
        for i, val in enumerate(grid):
            for j, _ in enumerate(val):
                stack = [(i,j)]
                cur = 0
                while stack:
                    cur_i, cur_j = stack.pop()
                    if cur_i < 0 or cur_j < 0 or cur_i == len(grid) or cur_j == len(grid[0]) or grid[cur_i][cur_j] != 1:
                        continue
                    cur += 1
                    grid[cur_i][cur_j] = 0
                    for di, dj in move:
                        next_i,next_j = di+cur_i, dj+cur_j
                        stack.append((next_i,next_j))
                ans = max(cur,ans)
        return ans

BFS

class Solution:
    def maxAreaOfIsland(self, grid: List[List[int]]) -> int:
        ans = 0
        move = [[1,0],[-1,0],[0,1],[0,-1]]
        for i,val in enumerate(grid):
            for j, _ in enumerate(val):
                queue = [(i,j)]
                cur = 0
                while queue:
                    cur_i,cur_j = queue.pop(0)
                    if cur_i < 0 or cur_j < 0 or cur_i == len(grid) or cur_j == len(grid[0]) or grid[cur_i][cur_j] != 1:
                        continue
                    grid[cur_i][cur_j] = 0
                    cur += 1
                    for di,dj in move:
                        next_i,next_j = cur_i + di,cur_j + dj
                        queue.append((next_i,next_j))
                ans = max(cur,ans)
        return ans



934. 最短的桥 (medium)

https://leetcode-cn.com/problems/shortest-bridge/

class Solution:
    def shortestBridge(self, grid: List[List[int]]) -> int:
        queue = []
        move = [[1, 0], [-1, 0], [0, 1], [0, -1]]

        def dfs(grid, i, j):
            if i < 0 or j < 0 or i == len(grid) or j == len(grid[0]) or grid[i][j] != 1:
                return
            grid[i][j] = 2
            queue.append((i, j))
            for di, dj in move:
                next_i = i + di
                next_j = j + dj
                dfs(grid, next_i, next_j)

        find = False
        for i in range(len(grid)):
            for j in range(len(grid[0])):
                if not find and grid[i][j] == 1:
                    dfs(grid, i, j)
                    find = True
        search = 0
        while queue:
            for _ in range(len(queue)):
                cur_i, cur_j = queue.pop(0)
                for di, dj in move:
                    next_i, next_j = cur_i + di, cur_j + dj
                    if next_i < 0 or next_j < 0 or next_i == len(grid) or next_j == len(grid[0]) or grid[next_i][next_j] == 2:
                        continue
                    if grid[next_i][next_j] == 1:
                        return search
                    grid[next_i][next_j] = 2
                    queue.append((next_i, next_j))
            search += 1
        return search            

DFS + BFS

547. 省份数量 (medium)

https://leetcode-cn.com/problems/number-of-provinces/

class Solution:
    def findCircleNum(self, isConnected: List[List[int]]) -> int:
        def dfs(i):
            visited[i] = 1
            for j in range(city):
                if visited[j] == 0 and isConnected[i][j] == 1:
                    dfs(j)

        city = len(isConnected)
        visited = city * [0]
        province = 0
        for i in range(city):
            if visited[i] == 0:
                dfs(i)
                province += 1
        return province

207. 课程表 (medium, 拓扑)

https://leetcode.cn/problems/course-schedule/

class Solution:
    def canFinish(self, numCourses: int, prerequisites: List[List[int]]) -> bool:
        if prerequisites == []:
            return True

        adj = [[] for i in range(numCourses)]
        in_degree = [0 for _ in range(numCourses)]

        for cur, pre in prerequisites:
            adj[pre].append(cur)
            in_degree[cur] += 1

        queue = []
        for i in range(numCourses):
            if in_degree[i] == 0:
                queue.append(i)

        while queue:
            numCourses -= 1
            cur = queue.pop(0)
            for i in range(numCourses): #这步的检索啥B了,直接用邻接表查链接的下一个就行了
                try:
                    if in_degree[adj[cur][i]] > 0:
                        in_degree[adj[cur][i]] -= 1
                except:
                    continue
                if in_degree[adj[cur][i]] == 0:
                    queue.append(adj[cur][i])
        return numCourses == 0
  1. 入度表 BFS
class Solution:
    def canFinish(self, numCourses: int, prerequisites: List[List[int]]) -> bool:
        if prerequisites == []:
            return True

        adj = [[] for i in range(numCourses)]
        in_degree = [0 for _ in range(numCourses)]

        for cur, pre in prerequisites:
            adj[pre].append(cur)
            in_degree[cur] += 1

        queue = []
        for i in range(numCourses):
            if in_degree[i] == 0:
                queue.append(i)

        while queue:
            numCourses -= 1
            cur = queue.pop(0)
            for j in adj[cur]:
                if in_degree[j] > 0:
                    in_degree[j] -= 1
                if in_degree[j] == 0:
                    queue.append(j)
        return numCourses == 0
  1. DFS
class Solution:
    def canFinish(self, numCourses: int, prerequisites: List[List[int]]) -> bool:
        if prerequisites == []:
            return True
        visited = [0 for _ in range(numCourses)]
        def dfs(adj, cur, visited):
            if visited[cur] == 1:
                return False
            if visited[cur] == 2:
                return True
            visited[cur] = 1
            for next_node in adj[cur]:
                if not dfs(adj, next_node, visited):
                    return False
            visited[cur] = 2
            return True
        adj = [[] for i in range(numCourses)]
        for cur, pre in prerequisites:
            adj[pre].append(cur)
            
        for i in range(numCourses):
            if not dfs(adj, i , visited):
                return False
        return True
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值