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
View Code

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
View Code

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
View Code

 

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)
View Code

 

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
View Code

 

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
View Code

 

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
View Code

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)
View Code

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
View Code

 NC102  最近公共祖先

给定一棵二叉树以及这棵树上的两个节点 o1 和 o2,请找到 o1 和 o2 的最近公共祖先节点。 
示例1

输入-[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
View Code

 NC6 二叉树的最大路径和

题目描述

给定一个二叉树,请计算节点值之和最大的路径的节点值之和是多少。
这个路径的开始节点和结束节点可以是二叉树中的任意节点
例如:
给出以下的二叉树,
 
返回的结果为6
示例1

输入:{-2,1}

返回值:1

示例2

输入:{-2,#,-3}

返回值:-2

问题分解,求树的最大路径,递归树的节点
有三种可能:

  1. 最大路径经过该节点本身从左子树到右子树
  2. 最大路径经过节点本身向父节点发展
  3. 最大路径就是节点本身

可以将左右边子树返回的满足情况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         
View Code

 NC 138 矩阵最长递增路径

题目描述

给定一个矩阵,矩阵内所有数均为非负整数。
求一条路径,该路径上所有数是递增的。
这个路径必须满足以下条件:
1、对于每个单元格,你可以往上,下,左,右四个方向移动。 你不能在对角线方向上移动或移动到边界外。
2、你不能走重复的单元格。即每个格子最多只能走一次。
示例1

输入

[[1,2,3],[4,5,6],[7,8,9]]

返回值

5

说明

1->2->3->6->9即可。当然这种递增路径不是唯一的。  
示例2

输入

[[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
View Code

 

posted @ 2020-03-24 11:01  aiwenhua_0610  阅读(100)  评论(0编辑  收藏  举报