DFS(一)
100. 相同的树
给定两个二叉树,编写一个函数来检验它们是否相同。
如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。
示例 1:
输入: 1 1 / \ / \ 2 3 2 3 [1,2,3], [1,2,3] 输出: true
示例 2:
输入: 1 1 / \ 2 2 [1,2], [1,null,2] 输出: false
示例 3:
输入: 1 1 / \ / \ 2 1 1 2 [1,2,1], [1,1,2] 输出: false
1 # Definition for a binary tree node. 2 # class TreeNode: 3 # def __init__(self, x): 4 # self.val = x 5 # self.left = None 6 # self.right = None 7 8 class Solution: 9 def isSameTree(self, p: TreeNode, q: TreeNode) -> bool: 10 if not p and not q: 11 return True 12 elif p is not None and q is not None: 13 if p.val == q.val: 14 return self.isSameTree(p.left, q.left) and self.isSameTree(p.right, q.right) 15 else: 16 return False 17 else: 18 return False
101. 对称二叉树
给定一个二叉树,检查它是否是镜像对称的。
例如,二叉树 [1,2,2,3,4,4,3]
是对称的。
1 / \ 2 2 / \ / \ 3 4 4 3
但是下面这个 [1,2,2,null,3,null,3]
则不是镜像对称的:
1 / \ 2 2 \ \ 3 3
说明:
如果你可以运用递归和迭代两种方法解决这个问题,会很加分
1 # Definition for a binary tree node. 2 # class TreeNode: 3 # def __init__(self, x): 4 # self.val = x 5 # self.left = None 6 # self.right = None 7 8 class Solution: 9 10 def isSymmetric(self, root: TreeNode) -> bool: 11 if not root: 12 return True 13 14 return self.isMirror(root.left, root.right) 15 16 17 def isMirror(self, p: TreeNode, q: TreeNode) -> bool: 18 if not p and not q: 19 return True 20 elif p is not None and q is not None: 21 22 return self.isMirror(p.left, q.right) and self.isMirror(p.right, q.left) and p.val == q.val 23 else: 24 return False 25 26
104. 二叉树的最大深度
给定一个二叉树,找出其最大深度。
二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。
说明: 叶子节点是指没有子节点的节点。
示例:
给定二叉树 [3,9,20,null,null,15,7]
,
3 / \ 9 20 / \ 15 7
返回它的最大深度 3 。
1 # Definition for a binary tree node. 2 # class TreeNode: 3 # def __init__(self, x): 4 # self.val = x 5 # self.left = None 6 # self.right = None 7 8 class Solution: 9 def maxDepth(self, root: TreeNode) -> int: 10 if root is not None: 11 HL = self.maxDepth(root.left) 12 HR = self.maxDepth(root.right) 13 MaxH = max(HL, HR) 14 return (MaxH + 1) 15 else: 16 return 0
108. 将有序数组转换为二叉搜索树
将一个按照升序排列的有序数组,转换为一棵高度平衡二叉搜索树。
本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1。
示例:
给定有序数组: [-10,-3,0,5,9], 一个可能的答案是:[0,-3,9,-10,null,5],它可以表示下面这个高度平衡二叉搜索树: 0 / \ -3 9 / / -10 5
1 # Definition for a binary tree node. 2 # class TreeNode: 3 # def __init__(self, x): 4 # self.val = x 5 # self.left = None 6 # self.right = None 7 8 class Solution: 9 def sortedArrayToBST(self, nums: List[int]) -> TreeNode: 10 begin = 0 11 end = len(nums) - 1 12 if end == -1: 13 return None 14 15 mid = (begin + end) >>1 16 17 x = nums[mid] 18 newTreeNode = TreeNode(x) 19 left_nums = nums[0:mid] 20 right_nums = nums[mid+1:end+1] 21 newTreeNode.left = self.sortedArrayToBST(left_nums) 22 newTreeNode.right = self.sortedArrayToBST(right_nums) 23 return newTreeNode
109. 有序链表转换二叉搜索树
给定一个单链表,其中的元素按升序排序,将其转换为高度平衡的二叉搜索树。
本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1。
示例:
给定的有序链表: [-10, -3, 0, 5, 9], 一个可能的答案是:[0, -3, 9, -10, null, 5], 它可以表示下面这个高度平衡二叉搜索树: 0 / \ -3 9 / / -10 5
1 # Definition for singly-linked list. 2 # class ListNode: 3 # def __init__(self, x): 4 # self.val = x 5 # self.next = None 6 7 # Definition for a binary tree node. 8 # class TreeNode: 9 # def __init__(self, x): 10 # self.val = x 11 # self.left = None 12 # self.right = None 13 14 class Solution: 15 16 def sortedListToBST(self, head: ListNode) -> TreeNode: 17 nums = self.ListToArray(head) 18 root = self.sortedArrayToBST(nums) 19 return root 20 21 def sortedArrayToBST(self, nums: list) -> TreeNode: 22 if nums is None: 23 return None 24 begin = 0 25 end = len(nums) - 1 26 if begin > end: 27 return None 28 mid = (begin + end) >> 1 29 root = TreeNode(nums[mid]) 30 root.left = self.sortedArrayToBST(nums[begin:mid]) 31 root.right = self.sortedArrayToBST(nums[mid+1:end+1]) 32 return root 33 34 def ListToArray(self, head: ListNode)->list: 35 nums = list() 36 while head is not None: 37 nums.append(head.val) 38 head =head.next 39 return nums
110. 平衡二叉树
给定一个二叉树,判断它是否是高度平衡的二叉树。
本题中,一棵高度平衡二叉树定义为:
一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过1。
示例 1:
给定二叉树 [3,9,20,null,null,15,7]
3 / \ 9 20 / \ 15 7
返回 true
。
示例 2:
给定二叉树 [1,2,2,3,3,null,null,4,4]
1 / \ 2 2 / \ 3 3 / \ 4 4
返回 false
。
1 # Definition for a binary tree node. 2 # class TreeNode: 3 # def __init__(self, x): 4 # self.val = x 5 # self.left = None 6 # self.right = None 7 8 class Solution: 9 def isBalanced(self, root: TreeNode) -> bool: 10 if root is None: 11 return True 12 13 HL = 0 14 HR = 0 15 if root.left is not None: 16 HL = self.maxDepth(root.left) 17 if root.right is not None: 18 HR = self.maxDepth(root.right) 19 20 if abs(HL-HR) >= 2 : 21 return False 22 else: 23 return self.isBalanced(root.left) and self.isBalanced(root.right) 24 25 26 def maxDepth(self, root: TreeNode) -> int: 27 if root is not None: 28 HL = self.maxDepth(root.left) 29 HR = self.maxDepth(root.right) 30 MaxH = max(HL, HR) 31 return (MaxH + 1) 32 else: 33 return 0
111. 二叉树的最小深度
给定一个二叉树,找出其最小深度。
最小深度是从根节点到最近叶子节点的最短路径上的节点数量。
说明: 叶子节点是指没有子节点的节点。
示例:
给定二叉树 [3,9,20,null,null,15,7]
,
3 / \ 9 20 / \ 15 7
返回它的最小深度 2
1 # Definition for a binary tree node. 2 # class TreeNode: 3 # def __init__(self, x): 4 # self.val = x 5 # self.left = None 6 # self.right = None 7 8 class Solution: 9 def minDepth(self, root: TreeNode) -> int: 10 if root is None: 11 return 0 12 elif root.left is None and root.right is None: 13 return 1 14 elif not root.left and root.right: 15 RH = self.minDepth(root.right) 16 return 1+RH 17 elif root.left and not root.right: 18 LH = self.minDepth(root.left) 19 return 1+LH 20 else: 21 RH = self.minDepth(root.right) 22 LH = self.minDepth(root.left) 23 return 1 + min(LH, RH)
98. 验证二叉搜索树
给定一个二叉树,判断其是否是一个有效的二叉搜索树。
假设一个二叉搜索树具有如下特征:
- 节点的左子树只包含小于当前节点的数。
- 节点的右子树只包含大于当前节点的数。
- 所有左子树和右子树自身必须也是二叉搜索树。
示例 1:
输入: 2 / \ 1 3 输出: true
示例 2:
输入: 5 / \ 1 4 / \ 3 6 输出: false 解释: 输入为: [5,1,4,null,null,3,6]。 根节点的值为 5 ,但是其右子节点值为 4 。
1 # Definition for a binary tree node. 2 # class TreeNode: 3 # def __init__(self, x): 4 # self.val = x 5 # self.left = None 6 # self.right = None 7 8 class Solution: 9 def isValidBST(self, root: TreeNode) -> bool: 10 inorder_res = self.inorderBST(root) 11 inorder_res_len = len(inorder_res) 12 13 for i in range(inorder_res_len-1): 14 if inorder_res[i+1] <= inorder_res[i]: 15 return False 16 17 return True 18 19 20 def inorderBST(self, root: TreeNode) -> list: 21 if not root: 22 return [] 23 24 res = self.inorderBST(root.left) 25 res = res + [root.val] 26 res = res + self.inorderBST(root.right) 27 28 return res
105. 从前序与中序遍历序列构造二叉树
根据一棵树的前序遍历与中序遍历构造二叉树。
注意:
你可以假设树中没有重复的元素。
例如,给出
前序遍历 preorder = [3,9,20,15,7] 中序遍历 inorder = [9,3,15,20,7]
返回如下的二叉树:
3 / \ 9 20 / \ 15 7
1 # Definition for a binary tree node. 2 # class TreeNode: 3 # def __init__(self, x): 4 # self.val = x 5 # self.left = None 6 # self.right = None 7 8 class Solution: 9 def buildTree(self, preorder: List[int], inorder: List[int]) -> TreeNode: 10 if len(preorder) == 0: 11 return None 12 13 x = preorder[0] 14 x_index = inorder.index(x) 15 16 left_inorder = inorder[0:x_index] 17 right_inorder = inorder[x_index+1:len(inorder)] 18 19 left_preorder = preorder[1:len(left_inorder)+1] 20 right_preorder = preorder[len(left_inorder)+1:len(inorder)] 21 22 leftTreeNode = self.buildTree(left_preorder, left_inorder) 23 rightTreeNode = self.buildTree(right_preorder, right_inorder) 24 25 NewTreeNode = TreeNode(x) 26 NewTreeNode.left = leftTreeNode 27 NewTreeNode.right = rightTreeNode 28 return NewTreeNode
106. 从中序与后序遍历序列构造二叉树
根据一棵树的中序遍历与后序遍历构造二叉树。
注意:
你可以假设树中没有重复的元素。
例如,给出
中序遍历 inorder = [9,3,15,20,7] 后序遍历 postorder = [9,15,7,20,3]
返回如下的二叉树:
3 / \ 9 20 / \ 15 7
1 # Definition for a binary tree node. 2 # class TreeNode: 3 # def __init__(self, x): 4 # self.val = x 5 # self.left = None 6 # self.right = None 7 8 class Solution: 9 def buildTree(self, inorder: List[int], postorder: List[int]) -> TreeNode: 10 if len(postorder) == 0: 11 return None 12 13 x = postorder[-1] 14 x_index = inorder.index(x) 15 16 left_inorder = inorder[0:x_index] 17 right_inorder = inorder[x_index+1:len(inorder)] 18 19 left_postorder = postorder[0:len(left_inorder)] 20 right_postorder = postorder[len(left_inorder):len(inorder)-1] 21 22 leftTreeNode = self.buildTree(left_inorder, left_postorder) 23 rightTreeNode = self.buildTree(right_inorder, right_postorder) 24 25 NewTreeNode = TreeNode(x) 26 NewTreeNode.left = leftTreeNode 27 NewTreeNode.right = rightTreeNode 28 return NewTreeNode
112. 路径总和
给定一个二叉树和一个目标和,判断该树中是否存在根节点到叶子节点的路径,这条路径上所有节点值相加等于目标和。
说明: 叶子节点是指没有子节点的节点。
示例:
给定如下二叉树,以及目标和 sum = 22
,
5 / \ 4 8 / / \ 11 13 4 / \ \ 7 2 1
返回 true
, 因为存在目标和为 22 的根节点到叶子节点的路径 5->4->11->2
。
1 # Definition for a binary tree node. 2 # class TreeNode: 3 # def __init__(self, x): 4 # self.val = x 5 # self.left = None 6 # self.right = None 7 8 class Solution: 9 def hasPathSum(self, root: TreeNode, Sum: int) -> bool: 10 if root is None: 11 return False 12 Sum = Sum - root.val 13 if not root.left and not root.right: 14 return Sum == 0 15 16 LV = self.hasPathSum(root.left, Sum) 17 RV = self.hasPathSum(root.right, Sum) 18 if LV or RV: 19 return True 20 else: 21 return False
113. 路径总和 II
给定一个二叉树和一个目标和,找到所有从根节点到叶子节点路径总和等于给定目标和的路径。
说明: 叶子节点是指没有子节点的节点。
示例:
给定如下二叉树,以及目标和 sum = 22
,
5 / \ 4 8 / / \ 11 13 4 / \ / \ 7 2 5 1
返回:
[ [5,4,11,2], [5,8,4,5] ]
1 # Definition for a binary tree node. 2 # class TreeNode: 3 # def __init__(self, x): 4 # self.val = x 5 # self.left = None 6 # self.right = None 7 #from copy import deepcopy 8 class Solution: 9 10 def pathSum(self, root: TreeNode, Sum: int) -> List[List[int]]: 11 res = list() 12 self.__dfs(root, Sum, list(), res) 13 return res 14 15 def __dfs(self, root: TreeNode, residue: int, path:list, res:list): 16 if root is None: 17 return 18 residue = residue - root.val 19 path = path + [root.val] 20 if not root.left and not root.right: 21 if residue == 0: 22 res.append(path[:]) 23 return 24 self.__dfs(root.left, residue, path, res) 25 self.__dfs(root.right, residue, path, res)
114. 二叉树展开为链表
给定一个二叉树,原地将它展开为链表。
例如,给定二叉树
1 / \ 2 5 / \ \ 3 4 6
将其展开为:
1 \ 2 \ 3 \ 4 \ 5 \ 6
1 # Definition for a binary tree node. 2 # class TreeNode: 3 # def __init__(self, x): 4 # self.val = x 5 # self.left = None 6 # self.right = None 7 8 class Solution: 9 def flatten(self, root: TreeNode) -> None: 10 """ 11 Do not return anything, modify root in-place instead. 12 """ 13 if root is None: 14 return 15 self.flatten(root.left) 16 self.flatten(root.right) 17 18 if root.left != None: 19 point = root.left 20 while point.right: 21 point = point.right 22 23 point.right = root.right 24 root.right = root.left 25 root.left = None
NC102 最近公共祖先
输入-[3,5,1,6,2,0,8,#,#,7,4],5,1
返回值-3
1 # class TreeNode: 2 # def __init__(self, x): 3 # self.val = x 4 # self.left = None 5 # self.right = None 6 7 # 8 # 9 # @param root TreeNode类 10 # @param o1 int整型 11 # @param o2 int整型 12 # @return int整型 13 # 14 class Solution: 15 def lowestCommonAncestor(self , root , o1 , o2 ): 16 # write code here 17 res = self.__dfs(root, o1, o2) 18 # if not res: 19 # return -1 20 return res.val 21 22 def __dfs(self, root, o1, o2): 23 if not root or o1 == root or o2 == root: 24 return root 25 26 left = self.__dfs(root.left, o1, o2) 27 right = self.__dfs(root.right, o1, o2) 28 29 if left and not right: 30 return left 31 elif right and not left: 32 return right 33 else: 34 return root
NC6 二叉树的最大路径和
题目描述
这个路径的开始节点和结束节点可以是二叉树中的任意节点
例如:
给出以下的二叉树,
返回的结果为6
输入:{-2,1}
返回值:1
示例2
输入:{-2,#,-3}
返回值:-2
问题分解,求树的最大路径,递归树的节点
有三种可能:
- 最大路径经过该节点本身从左子树到右子树
- 最大路径经过节点本身向父节点发展
- 最大路径就是节点本身
可以将左右边子树返回的满足情况2的最大路径和f(left),f(right),以及节点本身值val, 做一个组合,假设当前最大值是MAX: MAX = max(val, f(left)+val+f(right), f(left)+val, f(right)+val)
因为要满足递归条件,向上级返回的f(n)只能是情况2或者3
f(n) = max(val, f(left)+val, f(right)+val)
1 # class TreeNode: 2 # def __init__(self, x): 3 # self.val = x 4 # self.left = None 5 # self.right = None 6 7 # 8 # 9 # @param root TreeNode类 10 # @return int整型 11 # 12 import sys 13 class Solution: 14 def __init__(self): 15 self.global_val = -sys.maxsize - 1 16 17 def maxPathSum(self , root): 18 # write code here 19 # self.global_val = -sys.maxsize - 1 20 21 def __dfs(root): 22 if not root: 23 return 0 24 left = __dfs(root.left) 25 right = __dfs(root.right) 26 self.global_val = max(self.global_val, root.val+left+right) 27 28 return max(0, max(left,right)+root.val) 29 30 __dfs(root) 31 return self.global_val 32
NC 138 矩阵最长递增路径
题目描述
输入
[[1,2,3],[4,5,6],[7,8,9]]
返回值
5
说明
1->2->3->6->9即可。当然这种递增路径不是唯一的。
输入
[[1,2],[4,3]]
返回值
4
说明
1->2->3->4
备注:
矩阵的长和宽均不大于1000,矩阵内每个数不大于100
1 # 2 # 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 3 # 递增路径的最大长度 4 # @param matrix int整型二维数组 描述矩阵的每个数 5 # @return int整型 6 # 7 class Solution: 8 def dfs(self, matrix, dp, i, j): 9 if i>=len(matrix) or i<0 or j>=len(matrix[0]) or j<0: 10 return 0 11 if dp[i][j]!=0: 12 return dp[i][j] 13 a, b, c, d = 0, 0, 0, 0 14 if i+1<len(matrix) and matrix[i][j]<matrix[i+1][j]: 15 a = self.dfs(matrix, dp, i+1, j) 16 if i-1>=0 and matrix[i][j]<matrix[i-1][j]: 17 b = self.dfs(matrix, dp, i-1, j) 18 if j+1<len(matrix[0]) and matrix[i][j]<matrix[i][j+1]: 19 c = self.dfs(matrix, dp, i, j+1) 20 if j-1>=0 and matrix[i][j]<matrix[i][j-1]: 21 d = self.dfs(matrix, dp, i, j-1) 22 dp[i][j] = max(a, b, c, d, 0)+1 23 return dp[i][j] 24 25 def solve(self , matrix ): 26 # write code here 27 if not matrix or not matrix[0]: 28 return None 29 num = 0 30 dp = [[0]*len(matrix[0]) for _ in range(len(matrix))] 31 32 for i in range(len(matrix)): 33 for j in range(len(matrix[0])): 34 dp[i][j] = self.dfs(matrix, dp, i, j) 35 num = max(num, dp[i][j]) 36 return num