关于二叉树
tag:tree
二叉树的遍历
中序遍历
Given a binary tree, return the inorder traversal of its nodes’ values.
For example:
Given binary tree [1,null,2,3],
return [1,3,2].
递归recursively
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| class Solution(object): def inorderTraversal(self, root): """ :type root: TreeNode :rtype: List[int] """ res = [] if root == None: return res self.helper(root, res) return res def helper(self, root, res): if root: self.helper(root.left, res) res.append(root.val) self.helper(root.right, res)
|
迭代iteratively
1 2 3 4 5 6 7 8 9 10 11
| def inorderTraversal(self, root): res, stack = [], [] while True: while root: stack.append(root) root = root.left if not stack: return res node = stack.pop() res.append(node.val) root = node.right
|
前序遍历 根左右
144. Binary Tree Preorder Traversal
Given a binary tree, return the preorder traversal of its nodes’ values.
For example:
Given binary tree {1,#,2,3},
return [1,2,3].
1 2 3 4 5 6 7 8 9 10
| def preorderTraversal(self, root): ret = [] stack = [root] while stack: node = stack.pop() if node: ret.append(node.val) stack.append(node.right) stack.append(node.left) return ret
|
层序遍历
Given a binary tree, return the level order traversal of its nodes’ values. (ie, from left to right, level by level).
For example:
Given binary tree [3,9,20,null,null,15,7],
return its level order traversal as:
1 2 3 4 5
| [ [3], [9,20], [15,7] ]
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| class Solution(object): def levelOrder(self, root): """ :type root: TreeNode :rtype: List[List[int]] """ if not root: return [] ans, level = [], [root] while level: ans.append([node.val for node in level]) temp = [] for node in level: temp.extend([node.left, node.right]) print temp level = [leaf for leaf in temp if leaf] return ans
|
Path Sum系列
Given a binary tree and a sum, determine if the tree has a root-to-leaf path such that adding up all the values along the path equals the given sum.
For example:
Given the below binary tree and sum = 22,
1 2 3 4 5 6 7
| 5 / \ 4 8 / / \ 11 13 4 / \ \ 7 2 1
|
return true, as there exist a root-to-leaf path 5->4->11->2 which sum is 22.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| # Definition for a binary tree node. # class TreeNode(object): # def __init__(self, x): # self.val = x # self.left = None # self.right = None class Solution(object): def hasPathSum(self, root, sum): """ :type root: TreeNode :type sum: int :rtype: bool """ if root == None: return False if root.val == sum and root.left == None and root.right == None: return True sum = sum - root.val return self.hasPathSum(root.left, sum) or self.hasPathSum(root.right, sum)
|
Given a binary tree and a sum, find all root-to-leaf paths where each path’s sum equals the given sum.
For example:
Given the below binary tree and sum = 22,
1 2 3 4 5 6 7
| 5 / \ 4 8 / / \ 11 13 4 / \ / \ 7 2 5 1
|
return
[
[5,4,11,2],
[5,8,4,5]
]
tag: dfs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| class Solution(object): def pathSum(self, root, sum): """ :type root: TreeNode :type sum: int :rtype: List[List[int]] """ res = [] if root == None: return res self.helper(root, sum, [], res) return res def helper(self, root, sum, path, res): if root.val == sum and root.left == None and root.right == None: path.append(root.val) res.append(path) if root.left: self.helper(root.left, sum - root.val, path+[root.val], res) if root.right: self.helper(root.right, sum - root.val, path+[root.val], res)
|
You are given a binary tree in which each node contains an integer value.
Find the number of paths that sum to a given value.
The path does not need to start or end at the root or a leaf, but it must go downwards (traveling only from parent nodes to child nodes).
The tree has no more than 1,000 nodes and the values are in the range -1,000,000 to 1,000,000.
Example:
root = [10,5,-3,3,2,null,11,3,-2,null,1], sum = 8
1 2 3 4 5 6 7 8
| 10 / \ 5 -3 / \ \ 3 2 11 / \ \ 3 -2 1
|
Return 3. The paths that sum to 8 are:
- 5 -> 3
- 5 -> 2 -> 1
- -3 -> 11
这道题让我们求二叉树的路径的和等于一个给定值,说明了这条路径不必要从根节点开始,可以是中间的任意一段,而且二叉树的节点值也是有正有负。
利用前序遍历,对于每个遍历到的节点进行处理,维护一个变量pre记录之前的路径和,然后用cur为pre加上当前节点值,如果cur等于sum,那么返回结果时要加一,然后对当前节点的左右节点调用递归函数求解
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| class Solution(object): def pathSum(self, root, sum): """ :type root: TreeNode :type sum: int :rtype: int """ if not root: return 0 return self.helper(root, 0, sum) + self.pathSum(root.left, sum) + self.pathSum(root.right, sum) def helper(self, node, pre, sum): if not node: return 0 cur = pre + node.val return (cur == sum) + self.helper(node.left, cur, sum) + self.helper(node.right, cur, sum)
|
卡特兰数
这道题要求可行的二叉查找树的数量,其实二叉查找树可以任意取根,只要满足中序遍历有序的要求就可以。从处理子问题的角度来看,选取一个结点为根,就把结点切成左右子树,以这个结点为根的可行二叉树数量就是左右子树可行二叉树数量的乘积,所以总的数量是将以所有结点为根的可行结果累加起来。写成表达式如下:
这是 卡特兰数 的一种定义方式,是一个典型的动态规划的定义方式(根据其实条件和递推式求解结果)。所以思路也很明确了,维护量 res[i] 表示含有 i 个结点的二叉查找树的数量。根据上述递推式依次求出 1 到 n 的的结果即可。
时间上每次求解 i 个结点的二叉查找树数量的需要一个 i 步的循环,总体要求 n 次,所以总时间复杂度是 O(1+2+…+n)=O(n^2)。空间上需要一个数组来维护,并且需要前 i 个的所有信息,所以是 O(n)。代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| class Solution(object): def numTrees(self, n): """ :type n: int :rtype: int """ if n <= 0: return 0 res = [0] * (n+1) res[0] = 1 res[1] = 1 for i in range(2, n+1): for j in range(i): res[i] += res[j] * res[i - j - 1] return res[n]
|
卡特兰数——维基百科
随便举个栗子:
C8取4除以5 = 8 7 6 5 / 5 4 3 2 * 1 = 14
下面这道题不是卡特兰数
Given an integer n, generate all structurally unique BST’s (binary search trees) that store values 1…n.
For example,
Given n = 3, your program should return all 5 unique BST’s shown below.
1 2 3 4 5 6
| 1 3 3 2 1 \ / / / \ \ 3 2 1 1 3 2 / / \ \ 2 1 2 3
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| class Solution(object): def generateTrees(self, n): """ :type n: int :rtype: List[TreeNode] """ if n == 0: return [] return self.helper(1, n + 1) def helper(self, start, end): res = [] if start == end: return None for tmp in range(start, end): left = self.helper(start, tmp) right = self.helper(tmp + 1, end) for i in left or [None]: for j in right or [None]: node = TreeNode(tmp) node.left = i node.right = j res.append(node) return res
|