102. Binary Tree Level Order Traversal
- # Definition for a binary tree node.
- # class TreeNode(object):
- # def __init__(self, val=0, left=None, right=None):
- # self.val = val
- # self.left = left
- # self.right = right
- class Solution(object):
- def levelOrder(self, root):
- """
- :type root: TreeNode
- :rtype: List[List[int]]
- """
-
- results = []
- if not root:
- return results
-
- que = deque()
- que.append(root)
- while len(que) != 0:
- size = len(que)
- result = []
- while size >0:
- node = que.popleft()
- result.append(node.val)
- if node.left is not None:
- que.append(node.left)
- if node.right is not None:
- que.append(node.right)
- size -= 1
- results.append(result)
- return results
二刷:
未ac。使用成栈了,然后搞错了。然后少考虑了root未空的情况。方法是写对了
- class Solution:
- def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:
- result =[]
- if not root:
- return result
- que = deque()
- que.append(root)
- while que:
- #统计栈里面的size
- size = len(que)
- temp = []
- while size > 0:
- temp1 = que.popleft()
- temp.append(temp1.val)
- if temp1.left is not None:
- que.append(temp1.left)
- if temp1.right is not None:
- que.append(temp1.right)
- size -= 1
- result.append(temp)
- return result
三刷
- var levelOrder = function(root) {
- // 层序遍历
- let stack = []
- let result = []
- if(root === null){
- return result
- }
- stack.push(root)
- while(stack.length){
- let size = stack.length
- let temp = []
- for(let i = 0; i < size; i++){
- let node = stack.shift()
- if(node){
- temp.push(node.val)
- if(node.left){
- stack.push(node.left)
- }
- if(node.right){
- stack.push(node.right)
- }
- }
- }
- result.push(temp)
- }
- return result
- };
107. Binary Tree Level Order Traversal II
- class Solution(object):
- def levelOrderBottom(self, root):
- """
- :type root: TreeNode
- :rtype: List[List[int]]
- """
- if root is None:
- return []
- results =[]
- que = deque()
- que.append(root)
- while len(que) != 0:
- size = len(que)
- result = []
-
- while size >0:
- node = que.popleft()
- result.append(node.val)
- if node.left is not None:
- que.append(node.left)
- if node.right is not None:
- que.append(node.right)
- size -= 1
- results.append(result)
- return reversed(results)
二刷:
ac了
- class Solution:
- def levelOrderBottom(self, root: Optional[TreeNode]) -> List[List[int]]:
- #就是直接正着写,结果倒叙
- que = deque()
- result = []
- que.append(root)
- if not root:
- return result
- while que:
- size = len(que)
- temp = []
- while size>0:
- node = que.popleft()
- temp.append(node.val)
- if node.left is not None:
- que.append(node.left)
- if node.right is not None:
- que.append(node.right)
- size -= 1
- result.append(temp)
- new_result = []
- for i in range(len(result)-1,-1,-1):
- new_result.append(result[i])
- return new_result
三刷
- var levelOrderBottom = function(root) {
- // 层序遍历
- let stack = []
- let result = []
- if(root === null){
- return result
- }
- stack.push(root)
- while(stack.length){
- let size = stack.length
- let temp = []
- for(let i = 0; i < size; i++){
- let node = stack.shift()
- if(node){
- temp.push(node.val)
- if(node.left){
- stack.push(node.left)
- }
- if(node.right){
- stack.push(node.right)
- }
- }
- }
- result.unshift(temp)
- }
- console.log(result)
- return result
- };
199.二叉树的右视图
- class Solution(object):
- def rightSideView(self, root):
- """
- :type root: TreeNode
- :rtype: List[int]
- """
- if root is None:
- return []
- que = deque()
- que.append(root)
- result = []
- while len(que)!=0:
- size = len(que)
- node = que[-1]
- result.append(node.val)
- while size > 0:
- node = que.popleft()
- if node.left:
- que.append(node.left)
- if node.right:
- que.append(node.right)
- size -= 1
- return result
二刷:
未ac
- if root is None:
- return []
- que = deque()
- que.append(root)
- result = []
- while len(que)!=0:
- size = len(que)
- node = que[-1]
- print(node)
- result.append(node.val)
- while size > 0:
- node = que.popleft()
- if node.left:
- que.append(node.left)
- if node.right:
- que.append(node.right)
- size -= 1
- return result
三刷
- var rightSideView = function(root) {
- let stack = []
- let result = []
- if(root === null){
- return result
- }
- stack.push(root)
- while(stack.length){
- let size = stack.length
- let node = stack[stack.length-1]
- result.push(node.val)
- for(let i = 0; i < size; i++){
- let node = stack.shift()
- if(node){
- if(node.left){
- stack.push(node.left)
- }
- if(node.right){
- stack.push(node.right)
- }
- }
- }
- }
- console.log(result)
- return result
- };
637.二叉树的层平均值
- class Solution(object):
- def averageOfLevels(self, root):
- """
- :type root: TreeNode
- :rtype: List[float]
- """
- from numpy import *
- if root is None:
- return []
- results = []
- que = deque()
- que.append(root)
- while len(que) != 0:
- size = len(que)
- result = []
- while size>0:
- node = que.popleft()
- result.append(node.val)
- if node.left:
- que.append(node.left)
- if node.right:
- que.append(node.right)
- size -= 1
- results.append(mean(result))
- return results
二刷:ac
三刷
- var averageOfLevels = function(root) {
- let stack = []
- let result = []
- if(root === null){
- return result
- }
- stack.push(root)
- while(stack.length){
- let size = stack.length
- let temp = []
- for(let i = 0; i < size; i++){
- let node = stack.shift()
- temp.push(node.val)
- if(node){
- if(node.left){
- stack.push(node.left)
- }
- if(node.right){
- stack.push(node.right)
- }
- }
- }
- let avg = temp.reduce((a,b)=>a+b)/temp.length
- result.push(avg)
- }
- console.log(result)
- return result
- };
429. N-ary Tree Level Order Traversal
- class Solution(object):
- def levelOrder(self, root):
- """
- :type root: Node
- :rtype: List[List[int]]
- """
- results = []
- if not root:
- return results
-
- que = deque()
- que.append(root)
- while len(que) != 0:
- size = len(que)
- result = []
- while size >0:
- node = que.popleft()
- result.append(node.val)
- #存储的是一个列表
- if node.children is not None:
- #使用库函数,自动扩展队列
- que.extend(node.children)
- size -= 1
- results.append(result)
- return results
二刷:
未ac。可以注意到children的list,所以可使用之前我们做过数组的那一章节的extend函数进行拓展。
三刷
- var levelOrder = function(root) {
- let stack = []
- let result = []
- if(root === null){
- return result
- }
- stack.push(root)
- while(stack.length){
- let size = stack.length
- let temp = []
- for(let i = 0; i < size; i++){
- let node = stack.shift()
- if(node){
- temp.push(node.val)
- if(node.children){
- for(let index in node.children){
- stack.push(node.children[index])
- }
- }
- }
- }
- result.push(temp)
- }
- console.log(result)
- return result
-
- };
515. Find Largest Value in Each Tree Row
- results = []
- if not root:
- return results
-
- que = deque()
- que.append(root)
- while len(que) != 0:
- size = len(que)
- result = []
- while size >0:
- node = que.popleft()
- result.append(node.val)
- if node.left:
- que.append(node.left)
- if node.right:
- que.append(node.right)
- size -= 1
- maxx = max(result)
- results.append(maxx)
- return results
二刷:
ac
三刷
- var largestValues = function(root) {
- let stack = []
- let result = []
- if(root === null){
- return result
- }
- stack.push(root)
- while(stack.length){
- let size = stack.length
- let temp = []
- for(let i = 0; i < size; i++){
- let node = stack.shift()
- if(node){
- temp.push(node.val)
- if(node.left){
- stack.push(node.left)
- }
- if(node.right){
- stack.push(node.right)
- }
- }
- }
- result.push(Math.max(...temp))
- }
- console.log(result)
- return result
- };
116.填充每个节点的下一个右侧节点指针
这道题题目的意思是讲将右侧节点指向左侧,所以得给他加上一个next 的指向
- class Solution(object):
-
- def connect(self, root):
- """
- :type root: Node
- :rtype: Node
- """
- if root is None:
- return None
-
- queue = [root]
- while queue:
- n = len(queue)
- for i in range(n):
- node = queue.pop(0)
- if node.left:
- queue.append(node.left)
- if node.right:
- queue.append(node.right)
- if i == n - 1:
- break
- node.next = queue[0]
- return root
二刷:
未ac
三刷
- var connect = function(root) {
- let stack = []
- if(root === null){
- return null
- }
- stack.push(root)
- while(stack.length){
- let size = stack.length
- for(let i = 0; i < size; i++){
- let node = stack.shift()
- if (i < size - 1) {
- // 新的队头是node的右边元素
- node.next = stack[0];
- }
- if(node){
- if(node.left){
- stack.push(node.left)
- }
- if(node.right){
- stack.push(node.right)
- }
- }
- }
- }
- return root
- };
117.填充每个节点的下一个右侧节点指针II
-
- class Solution(object):
- def connect(self, root):
- """
- :type root: Node
- :rtype: Node
- """
- if root is None:
- return None
-
- queue = [root]
- while queue:
- n = len(queue)
- for i in range(n):
- node = queue.pop(0)
- if node.left:
- queue.append(node.left)
- if node.right:
- queue.append(node.right)
- if i == n - 1:
- break
- node.next = queue[0]
- return root
二刷:
未ac。
不知道如何指向后面的元素。需要利用que自己的一个属性。
- class Solution:
- def connect(self, root: 'Optional[Node]') -> 'Optional[Node]':
- if not root:
- return
- que = deque()
- que.append(root)
- while len(que) != 0:
- size = len(que)
- while size >0:
- node = que.popleft()
- if node.left:
- que.append(node.left)
- if node.right:
- que.append(node.right)
- if size == 1:
- break
- node.next = que[0]
- size -= 1
- return root
三刷
- let stack = []
- if(root === null){
- return null
- }
- stack.push(root)
- while(stack.length){
- let size = stack.length
- for(let i = 0; i < size; i++){
- let node = stack.shift()
- if (i < size - 1) {
- // 新的队头是node的右边元素
- node.next = stack[0];
- }
- if(node){
- if(node.left){
- stack.push(node.left)
- }
- if(node.right){
- stack.push(node.right)
- }
- }
- }
- }
- return root
104.二叉树的最大深度
- class Solution(object):
- def maxDepth(self, root):
- """
- :type root: TreeNode
- :rtype: int
- """
- count = 0
- if not root:
- return count
- que = deque()
- que.append(root)
- while len(que) != 0:
- size = len(que)
- while size >0:
- node = que.popleft()
- if node.left is not None:
- que.append(node.left)
- if node.right is not None:
- que.append(node.right)
- size -= 1
- count += 1
- return count
二刷:
ac
三刷
- var maxDepth = function(root) {
- let stack = []
- if(root === null){
- return null
- }
- stack.push(root)
- let count = 0
- while(stack.length){
- let size = stack.length
- for(let i = 0; i < size; i++){
- let node = stack.shift()
- if(node){
- if(node.left){
- stack.push(node.left)
- }
- if(node.right){
- stack.push(node.right)
- }
- }
- }
- count ++
- }
- return count
- };
111.二叉树的最小深度(这题没想出来)
当左右节点为空节点的时候,这就是最深度最低的
- class Solution(object):
- def minDepth(self, root):
- """
- :type root: TreeNode
- :rtype: int
- """
- if root is None:
- return 0
- que = [(root,1)]
-
- while len(que) != 0:
- node,depth = que.pop(0)
- #终止条件,当都为空,跳出循环
- if node.left is None and node.right is None:
- return depth
- if node.left is not None:
- que.append((node.left,depth+1))
- if node.right is not None:
- que.append((node.right,depth+1))
- #遍历完毕后,如果都没有找到的话,返回0
- return 0
重点:
不要忘记有空值得情况
que[0] 是要出队的
que[-1]是刚入队的
题目链接/文章讲解/视频讲解:代码随想录
二刷:ac。但是方法好像不对啊。我的方法是,如果遇到左右节点为空,就是最小的。跟上面的方法意思是类似的。只是它使用了个数组来记录
- class Solution:
- def minDepth(self, root: Optional[TreeNode]) -> int:
- if not root:
- return 0
- que = deque()
- que.append(root)
- result = 0
- while len(que) != 0:
- size = len(que)
- while size > 0:
- node = que.popleft()
- if node.left:
- que.append(node.left)
- if node.right:
- que.append(node.right)
- if node.right is None and node.left is None:
- return result+1
- size -= 1
- result += 1
- return result
- class Solution:
- def minDepth(self, root: Optional[TreeNode]) -> int:
- if not root:
- return 0
- que = deque()
- que.append([root,1])
- result = 0
- while len(que) != 0:
- size = len(que)
- while size > 0:
- node,depth = que.popleft()
- if node.left:
- que.append([node.left,depth+1])
- if node.right:
- que.append([node.right,depth+1])
- if node.right is None and node.left is None:
- return depth
- size -= 1
- return 0
- var minDepth = function(root) {
- let stack = []
- if(root === null){
- return null
- }
- stack.push(root)
- let count = 0
- while(stack.length){
- let size = stack.length
- for(let i = 0; i < size; i++){
- let node = stack.shift()
- if(node){
- if(node.left){
- stack.push(node.left)
- }
- if(node.right){
- stack.push(node.right)
- }
- if(node.right ===null&& node.left===null){
- return count +1
- }
- }
- }
- count ++
- }
- return count
- };
重点:
交换指针,而不是交换数值
- class Solution(object):
- def invertTree(self, root):
- """
- :type root: TreeNode
- :rtype: TreeNode
- """
- if root is None:
- return None
- #前序遍历
- #交换左右节点
- root.left,root.right = root.right,root.left
- #遍历左节点
- self.invertTree(root.left)
- #遍历右节点
- self.invertTree(root.right)
- return root
-
- if root is None:
- return None
- #后序遍历
-
- #遍历左节点
- self.invertTree(root.left)
- #遍历右节点
- self.invertTree(root.right)
- #交换左右节点
- root.left,root.right = root.right,root.left
- return root
-
- if root is None:
- return None
- #中序遍历
- #遍历左节点
- self.invertTree(root.left)
- #交换左右节点
- root.left,root.right = root.right,root.left
- #反转过后,右节点变左节点了,所以还得再次遍历左节点
- #遍历右节点
- self.invertTree(root.left)
- return root
重点:
应该用什么遍历方式:前序,后序(优先使用)/中序(比较麻烦)
递归三要素:
题目链接/文章讲解/视频讲解:代码随想录
二刷:未ac
迭代法处理前序遍历。广度优先算法。层序遍历,我这使用的是。
- class Solution:
- def invertTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
- if not root:
- return root
- que = deque()
- que.append(root)
- while len(que) != 0:
- size = len(que)
- while size > 0:
- node = que.popleft()
- node.left,node.right = node.right,node.left
- if node.left:
- que.append(node.left)
- if node.right:
- que.append(node.right)
- size -= 1
- return root
深度优先算法的前序遍历,要用栈!不能用队列,很容易有歧义的
- class Solution:
- def invertTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
- if not root:
- return root
- st = deque()
- st.append(root)
- while st:
- node = st.popleft()
- node.left, node.right = node.right, node.left #中
-
- if node.left:
- st.append(node.left) #左
- if node.right:
- st.append(node.right) #右
- return root
这里是深度优先算法的一个文档。得认真阅读。全忘记了
前序
- class Solution:
- def invertTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
- if not root:
- return root
- #深度优先算法,前序遍历,递归法
- stack = []
- stack.append(root)
- while stack:
- node = stack.pop()
- #中
- node.left,node.right = node.right,node.left
- #右
- if node.right:
- stack.append(node.right)
- #左
- if node.left:
- stack.append(node.left)
- return root
三刷
- var invertTree = function(root) {
- //我们先定义节点交换函数
- const invertNode = function(root, left, right) {
- let temp = left;
- left = right;
- right = temp;
- root.left = left;
- root.right = right;
- }
- //使用层序遍历
- let queue = [];
- if(root === null) {
- return root;
- }
- queue.push(root);
- while(queue.length) {
- let length = queue.length;
- while(length--) {
- let node = queue.shift();
- //节点处理逻辑
- invertNode(node, node.left, node.right);
- node.left && queue.push(node.left);
- node.right && queue.push(node.right);
- }
- }
- return root;
- };
- class Solution(object):
- def isSymmetric(self, root):
- """
- :type root: TreeNode
- :rtype: bool
- """
- if not root:
- return True
- return self.recursion(root.left,root.right)
- #本题需要判断,根节点的左右节点是否可以反转
- def recursion(self,left,right):
- #终止条件
- if left is None and right is not None:return False
- elif left is not None and right is None:return False
- elif left is None and right is None:return True
- elif left.val != right.val:return False
- outside = self.recursion(left.left, right.right)
- inside = self.recursion(left.right, right.left)
- issame = outside and inside
- return issame
重点:
这道题考察的是判断根节点的左子树和右子树是否可以反转。(先比较外侧,再比较内侧,如果都相同,那么可以翻转)
二叉树主要考察的是如何去遍历:这道题主要使用的是前序遍历或者后序遍历。
题目链接/文章讲解/视频讲解:代码随想录
三刷
- var isSymmetric = function(root) {
- const recursion = function(left,right){
- if(left === null && right !==null){
- return false
- }else if(left !== null && right === null){
- return false
- }else if(left === null && right === null){
- return true
- }else if(left.val !== right.val){
- return false
- }
- let outside = recursion(left.left,right.right)
- let inside = recursion(left.right,right.left)
- let isSame = outside && inside
- return isSame
- }
- return recursion(root.left,root.right)
-
-
- };
100相同的树
- class Solution:
- def isSameTree(self, p: Optional[TreeNode], q: Optional[TreeNode]) -> bool:
- #递归遍历
- #参数返回值
- #单层便利
- #终止条件
- def reversion(a,b):
- if a is None and b is None:
- return True
- elif a is not None and b is None:return False
- elif a is None and b is not None:return False
- elif a is not None and b is not None and a.val != b.val:return False
- #反转
- outside = reversion(a.left,b.left)
- inside = reversion(a.right,b.right)
- issame = outside and inside
- return issame
-
- #如果两棵树都为空值的话
- if not p and not q:
- return True
- return reversion(p,q)
三刷
- var isSameTree = function(p, q) {
- const recursion = function(node1,node2){
- if(node1 === null && node2 !==null){
- return false
- }else if(node1 !== null && node2 === null){
- return false
- }else if(node1 === null && node2 === null){
- return true
- }else if(node1.val !== node2.val){
- return false
- }
- let oneSide = recursion(node1.left,node2.left)
- let secSide = recursion(node1.right,node2.right)
- let isSame = oneSide && secSide
- return isSame
- }
- return recursion(p,q)
- };
- class Solution:
- def isSubtree(self, root: Optional[TreeNode], subRoot: Optional[TreeNode]) -> bool:
- #递归法
- def recursion(root,subroot):
- if root is None and subroot is None:
- return True
- elif root is not None and subroot is None:return False
- elif root is None and subroot is not None:return False
- elif root is not None and subroot is not None and root.val != subroot.val:return False
- left = recursion(root.left,subroot.left)
- right = recursion(root.right,subroot.right)
- issame = left and right
- return issame
- def dfs(root,subroot):
- #终止条件,因为是一直在移动root的,所以只用判断他是不是为空,如果是空,遍历完毕,返回false
- if root is None:
- return False
- if root.val == subroot.val and recursion(root,subroot):
- return True
- return dfs(root.left,subroot) or dfs(root.right,subroot)
- if not root and not subroot:
- return True
- return dfs(root,subRoot)
二刷:未ac
使用队列的写法
- class Solution:
- def isSymmetric(self, root: Optional[TreeNode]) -> bool:
- if root is None:
- return True
- que = deque()
- que.append(root.left)
- que.append(root.right)
- while que:
- leftnode = que.popleft()
- rightnode = que.popleft()
- if leftnode is None and rightnode is None:continue
- if leftnode is not None and rightnode is None:return False
- elif leftnode is None and rightnode is not None:return False
- elif leftnode is not None and rightnode is not None and leftnode.val != rightnode.val:return False
- #反转,将左边的右节点放入,
- que.append(leftnode.left)
- que.append(rightnode.right)
- que.append(leftnode.right)
- que.append(rightnode.left)
- return True
三刷
- var isSubtree = function(root, subRoot) {
- // 现遍历到相同的树再进行判断
- const recursion = function(node1,node2){
- if(node1 === null && node2 === null){
- return true
- }else if(node1 === null || node2 === null){
- return false
- }else if(node1.val !== node2.val){
- return false
- }
- let oneSide = recursion(node1.left,node2.left)
- let secSide = recursion(node1.right,node2.right)
- let isSame = oneSide && secSide
- return isSame
- }
- const dfs = (node) => {
- if (!node) return false;
- if (recursion(node, subRoot)) return true;
- return dfs(node.left) || dfs(node.right);
- }
- return dfs(root);
- };