和树有关的题目求深度 -> 可以利用层序遍历 -> 用到层序遍历就想到使用BFS


896. 单调数列 - 水题

  1. class Solution:
  2. def isMonotonic(self, A) -> bool:
  3. if sorted(A) == A or sorted(A, reverse=True) == A:
  4. return True
  5. return False

690. 员工的重要性 - 简单BFS

  1. class Solution:
  2. def getImportance(self, employees, id):
  3. """
  4. :type employees: Employee
  5. :type id: int
  6. :rtype: int
  7. """
  8. s = 0
  9. Q = []
  10. for i in employees:
  11. if i.id == id:
  12. Q.append(i)
  13. while len(Q) != 0:
  14. boss = Q.pop(0)
  15. importance = boss.importance
  16. subordinate = boss.subordinates
  17. s += importance
  18. for i in employees:
  19. if i.id in subordinate:
  20. Q.append(i)
  21. return s
  22. # e1 = Employee(1, 5, [2, 3])
  23. # e2 = Employee(2, 3, [])
  24. # e3 = Employee(3, 3, [])
  25. # Employ = [e1, e2, e3]
  26. # print(Solution().getImportance(Employ, 1))

111. 二叉树的最小深度 - 简单BFS

  1. """
  2. BFS就是对树的层序遍历,发现的第一个叶子节点一定是深度最小的
  3. """
  4. class Solution:
  5. def minDepth(self, root: TreeNode) -> int:
  6. if root == None:
  7. return 0
  8. Q = [(root, 1)]
  9. while len(Q) != 0:
  10. node, deepth = Q.pop(0)
  11. if node.left == None and node.right == None:
  12. return deepth
  13. if node.left:
  14. Q.append((node.left, deepth+1))
  15. if node.right:
  16. Q.append((node.right, deepth+1))

559. N叉树的最大深度 - 和楼上找最小深度思路一样

  1. """
  2. BFS结束后肯定是到了这个树的最后一层,设置一个层数标志位,不断更新标志位,则BFS退出后标志位的值就是最后一层的层数。
  3. """
  4. class Solution:
  5. def maxDepth(self, root) -> int:
  6. if root == None:
  7. return 0
  8. Q = [(root, 1)]
  9. m = 0
  10. while len(Q) != 0:
  11. node, deepth = Q.pop(0)
  12. m = deepth
  13. for i in node.children:
  14. Q.append((i, deepth+1))
  15. return m

993. 二叉树的堂兄弟节点

  1. """
  2. BFS - 记录每个节点的深度和父节点,再去比较题目中给定的x和y的深度与父节点
  3. """
  4. class Solution:
  5. def isCousins(self, root: TreeNode, x: int, y: int) -> bool:
  6. if root == None:
  7. return False
  8. # 节点,层数,父节点
  9. Q = [(root, 1, None)]
  10. checkOver = 0
  11. d = []
  12. par = []
  13. while len(Q) != 0:
  14. node, depth, parent = Q.pop(0)
  15. if node == None:
  16. break
  17. if node.val == x or node.val == y:
  18. checkOver += 1
  19. d.append(depth)
  20. if parent:
  21. par.append(parent.val)
  22. else:
  23. par.append(-10000)
  24. if checkOver == 2:
  25. break
  26. if node.left:
  27. Q.append((node.left, depth+1, node))
  28. if node.right:
  29. Q.append((node.right, depth+1, node))
  30. if d[0] == d[1] and par[0] != par[1]:
  31. return True
  32. return False

102. 二叉树的层次遍历

  1. """
  2. BFS - 利用set来记录层数
  3. """
  4. class Solution:
  5. def levelOrder(self, root: TreeNode):
  6. if root == None:
  7. return []
  8. Q = [(root, 1)]
  9. deepSet = set()
  10. deepSet.add(1)
  11. tmp = []
  12. result = []
  13. while len(Q) != 0:
  14. node, deepth = Q.pop(0)
  15. if deepth not in deepSet:
  16. deepSet.add(deepth)
  17. result.append(tmp)
  18. tmp = []
  19. tmp.append(node.val)
  20. if node.left:
  21. Q.append((node.left, deepth+1))
  22. if node.right:
  23. Q.append((node.right, deepth+1))
  24. result.append(tmp)
  25. return result

103. 二叉树的锯齿形层次遍历 - 和二叉树遍历完全一致

  1. """
  2. 两者代码的唯一不同在于锯齿形的遍历编号从0开始的奇数行需要逆转一下
  3. """
  4. class Solution:
  5. def zigzagLevelOrder(self, root: TreeNode):
  6. if root == None:
  7. return []
  8. Q = [(root, 1)]
  9. deepSet = set()
  10. deepSet.add(1)
  11. tmp = []
  12. result = []
  13. while len(Q) != 0:
  14. node, deepth = Q.pop(0)
  15. if deepth not in deepSet:
  16. deepSet.add(deepth)
  17. result.append(tmp)
  18. tmp = []
  19. tmp.append(node.val)
  20. if node.left:
  21. Q.append((node.left, deepth+1))
  22. if node.right:
  23. Q.append((node.right, deepth+1))
  24. result.append(tmp)
  25. # 唯一的差别就在这里
  26. for i in range(len(result)):
  27. if i % 2 == 1:
  28. result[i] = result[i][::-1]
  29. return result

127. 单词接龙 - 双向BFS

  1. """
  2. 使用最普通BFS模板会超时(暂无解决办法),本题可以思考为一棵树,根节点就是beginWord,它的子节点就是变换一个单词后的单词,子节点的子节点就是子节点变换一个单词... 然后在那一层发现了目标节点,返回该层的层数
  3. """
  4. class Solution:
  5. def ladderLength(self, beginWord: str, endWord: str, wordList) -> int:
  6. if beginWord == endWord:
  7. return 0
  8. Q = []
  9. for i in wordList:
  10. if self.OneDefferent(i, beginWord):
  11. Q.append((i, 1))
  12. s = set()
  13. while len(Q) != 0:
  14. word, step = Q.pop(0)
  15. # print(word)
  16. if word == endWord:
  17. return step+1
  18. if word in wordList:
  19. wordList.remove(word)
  20. for i in wordList:
  21. if self.OneDefferent(i, word):
  22. Q.append((i, step+1))
  23. return 0
  24. def OneDefferent(self,str1, str2):
  25. str1 = list(str1); str2 = list(str2)
  26. check = 0
  27. for i in range(len(str2)):
  28. if str1[i] != str2[i]:
  29. check += 1
  30. if check > 1 :
  31. return False
  32. if check == 1:
  33. return True
  1. """
  2. 评论中提到的双向BFS(还在理解中):
  3. 当某层数量过大的时候,BFS会耗时很多。所以采用两端一起走的方式,不断比较,那一头走的少就走那一头,如果有交集最后肯定会相遇。
  4. """
  5. class Solution:
  6. def ladderLength(self, beginWord: str, endWord: str, wordList) -> int:
  7. if endWord not in wordList:
  8. return 0
  9. head = {beginWord}
  10. tail = {endWord}
  11. wordSet = set(wordList)
  12. wordSet.remove(endWord)
  13. res = 0
  14. while head and tail:
  15. res += 1
  16. if len(head) > len(tail):
  17. head, tail = tail, head
  18. nextLevel = set()
  19. for i in head:
  20. for j in range(len(i)):
  21. for letter in range(97, 97+26):
  22. # 利用二十六个字母在每一个位置进行替换
  23. newWord = i[:j] + chr(letter) + i[j+1:]
  24. if newWord in tail:
  25. return res + 1
  26. if newWord not in wordSet:
  27. continue
  28. wordSet.remove(newWord)
  29. nextLevel.add(newWord)
  30. head = nextLevel
  31. return 0
  1. """
  2. BFS双向的模板:适用于从某个初始状态到某个终止状态求最短路径
  3. head = {初始状态}
  4. tail = {终止状态}
  5. while head and tail:
  6. # 每次都从短的开始
  7. if len(head) > len(tail):
  8. head, tail = tail, head
  9. nextLeval = set()
  10. for i in head:
  11. # 扩展下一层
  12. if 扩展的下一层的某个元素 in tail:
  13. # 表示已经找到了
  14. return
  15. head = nextLevel
  16. # 每次的head和tail都在更新为某层的状态
  17. """

433. 最小基因变化 - 套用上面的双向BFS模板

  1. """
  2. 和上面的单词结论几乎一致,都是每次给定一个初始状态、一个终止状态,改变一个字母,找到最小的变化(其实也就是找到最小路径)
  3. """
  4. class Solution:
  5. def minMutation(self, start: str, end: str, bank) -> int:
  6. change = ["A", "C", "G", "T"]
  7. if end not in bank or len(bank) == 0:
  8. return -1
  9. head = {start}
  10. tail = {end}
  11. bank.remove(end)
  12. res = 0
  13. while head and tail:
  14. res += 1
  15. if len(head) > len(tail):
  16. head, tail = tail, head
  17. nextLevel = set()
  18. # 拓展下一层
  19. for i in head:
  20. for j in range(len(i)):
  21. for cha in change:
  22. newGene = i[:j]+cha+i[j+1:]
  23. if newGene in tail:
  24. return res
  25. if newGene not in bank:
  26. continue
  27. nextLevel.add(newGene)
  28. # 已经走过的就不用再走了
  29. bank.remove(newGene)
  30. head = nextLevel
  31. return -1

Leetcode题解 - BFS部分题目代码+思路(896、690、111、559、993、102、103、127、433)的更多相关文章

  1. Leetcode题解 - DFS部分题目代码+思路(756、1034、1110、491、721、988)

    756. 金字塔转换矩阵 """ 学到的新知识: from collections import defaultditc可以帮我们初始化字典,不至于取到某个不存在的值的时 ...

  2. Leetcode题解 - 树、DFS部分简单题目代码+思路(700、671、653、965、547、473、46)

    700. 二叉搜索树中的搜索 - 树 给定二叉搜索树(BST)的根节点和一个值. 你需要在BST中找到节点值等于给定值的节点. 返回以该节点为根的子树. 如果节点不存在,则返回 NULL. 思路: 二 ...

  3. Leetcode题解 - 贪心算法部分简单题目代码+思路(860、944、1005、1029、1046、1217、1221)

    leetcode真的是一个学习阅读理解的好地方 860. 柠檬水找零 """ 因为用户支付的只会有5.10.20 对于10元的用户必须找一个5 对于20元的用户可以找(三 ...

  4. Leetcode题解 - DFS部分简单题目代码+思路(113、114、116、117、1020、494、576、688)

    这次接触到记忆化DFS,不过还需要多加练习 113. 路径总和 II - (根到叶子结点相关信息记录) """ 思路: 本题 = 根到叶子结点的路径记录 + 根到叶子结点 ...

  5. Leetcode题解 - 树部分简单题目代码+思路(105、106、109、112、897、257、872、226、235、129)

    树的题目中递归用的比较多(但是递归是真难弄 我

  6. Leetcode题解 - 链表简单部分题目代码+思路(21、83、203、206、24、19、876)

  7. 【LeetCode题解】二叉树的遍历

    我准备开始一个新系列[LeetCode题解],用来记录刷LeetCode题,顺便复习一下数据结构与算法. 1. 二叉树 二叉树(binary tree)是一种极为普遍的数据结构,树的每一个节点最多只有 ...

  8. leetcode题解-122买卖股票的最佳时期

    题目 leetcode题解-122.买卖股票的最佳时机:https://www.yanbinghu.com/2019/03/14/30893.html 题目详情 给定一个数组,它的第 i 个元素是一支 ...

  9. [LeetCode 题解] Spiral Matrix

    前言 [LeetCode 题解]系列传送门: http://www.cnblogs.com/double-win/category/573499.html 题目链接 54. Spiral Matrix ...

随机推荐

  1. 【Feign】@FeignClient相同名字错误 The bean 'xxx.FeignClientSpecification', defined in null, could not be registered

    The bean 'xxx.FeignClientSpecification', defined in null, could not be registered. A bean with that ...

  2. 2019年Spring核心知识点整理,看看你掌握了多少?

    前言 如今做Java尤其是web几乎是避免不了和Spring打交道了,但是Spring是这样的大而全,新鲜名词不断产生,学起来给人一种凌乱的感觉,在这里总结一下,理顺头绪. Spring 概述 Spr ...

  3. python爬虫--selenium模块.上来自己动!

    selenium 基本操作 from selenium import webdriver from time import sleep #实例化一个浏览器对象 bro = webdriver.Chro ...

  4. CCF-CSP题解 201903-3 损坏的RAID5

    先吐槽先吐槽!因为输入太大,需要用fgets,读n个字符或读到回车终止. char *fgets(char *str, int n, FILE *stream) 因为scanf模拟考试T了10+次.因 ...

  5. Vue基础简介

    目录 vue基础 一.导入vue 二.vue挂载点 三.vue变量 四.vue事件 五.vue文本指令 六.vue事件指令 七.vue属性指令 vue基础 一.导入vue 补充:vue的语句以及导入j ...

  6. Http协议 & Servlet

    Http协议&Servlet Http协议 什么是协议 双方在交互.通讯的时候遵守的一种规范.规则. http协议 针对网络上的客户端与服务器端在执行http请求的时候,遵守的一种规范.其实就 ...

  7. 【搞定Jvm面试】 JDK监控和故障处理工具揭秘

    本文已经收录自笔者开源的 JavaGuide: https://github.com/Snailclimb ([Java学习+面试指南] 一份涵盖大部分Java程序员所需要掌握的核心知识)如果觉得不错 ...

  8. Typroa 常用快捷键

    Typora 常用快捷键 文件操作 Ctrl + N :新建文件 Ctrl + shift + N :新建窗口 Ctrl + O :打开 Ctrl + P : 快速打开(快速打开之前编辑过的历史文件) ...

  9. IDEA 解决Project SDK is not defined

    IDEA 解决Project SDK is not defined 问题如下: 点击蓝字Setup SDK. 点击configure... 点击+,选择JDK. 选择jdk所在路径,点击确定. 选中, ...

  10. Golang 入门系列(十二)ORM框架gorm

    之前在已经介绍了用的github.com/go-sql-driver/mysql 访问数据库,不太了解的可以看看之前的文章 https://www.cnblogs.com/zhangweizhong/ ...