94. Binary Tree Inorder Traversal
二叉树中序遍历
递归方法:
func inorderTraversal(root *TreeNode) []int {
var result []int
return order(root, result)
}
func order(root *TreeNode, result []int) []int {
if root == nil {
return result
}
result = order(root.Left, result)
result = append(result, root.Val)
return order(root.Right, result)
}
非递归
func inorderTraversal(root *TreeNode) []int {
var result []int
var stack = list.New()
var t = root
for t != nil || stack.Len() != 0 {
for t != nil {
stack.PushBack(t)
t = t.Left
}
if stack.Len() != 0 {
var val = stack.Back()
var curNode = val.Value.(*TreeNode)
result = append(result, curNode.Val)
t = curNode.Right
stack.Remove(val)
}
}
return result
}
95. Unique Binary Search Trees II 独一无二的二叉搜索树之二
func generateTrees(n int) []*TreeNode {
if n <= 0 {
return nil
}
return genTrees(1, n)
}
func genTrees(start, end int) []*TreeNode {
var subTree = make([]*TreeNode, 0)
if start > end {
subTree = append(subTree, nil)
} else {
for i:=start; i<=end; i++ {
var leftSubTree = genTrees(start, i-1)
var rightSubTree = genTrees(i+1, end)
for j:=0; j<len(leftSubTree); j++ {
for k:=0; k<len(rightSubTree); k++ {
RootNode := &TreeNode{
Val: i,
Left: leftSubTree[j],
Right: rightSubTree[k],
}
subTree = append(subTree, RootNode)
}
}
}
}
return subTree
}
96. Unique Binary Search Trees
二叉搜索树的性质为:在任一结点r的左(右)子树中,所有结点(若存在)均小于(大于)r。更一般性的特点是:任何一棵二叉树是二叉搜索树,当且仅当其中序遍历序列单调非降。
Catalan Number卡特兰数的一个例子。卡特兰数的的递推公式:
98. [LeetCode] Validate Binary Search Tree 验证二叉搜索树
根据二叉搜索树特性,左<根<右
- 节点的左子树只包含小于当前节点的数。
- 节点的右子树只包含大于当前节点的数。
- 所有左子树和右子树自身必须也是二叉搜索树。
func isValidBST(root *TreeNode) bool {
const INT_MAX = int(^uint(0) >> 1)
const INT_MIN = ^INT_MAX
return validBST(root, INT_MIN, INT_MAX)
}
func validBST(root *TreeNode, left, right int) bool {
if root == nil {
return true
}
if root.Val <= left || root.Val >= right {
return false
}
return validBST(root.Left, left, root.Val) && validBST(root.Right, root.Val, right)
}
99. Recover Binary Search Tree 复原二叉搜索树
func inorder(root *TreeNode, first, second, pre **TreeNode) {
if root == nil {
return
}
inorder(root.Left, first, second, pre)
if (*pre).Val == -1 {
*pre = root
} else {
if (*pre).Val > root.Val {
if (*first).Val == -1 {
*first = *pre
}
*second = root
}
*pre = root
}
inorder(root.Right, first, second, pre)
}
func recoverTree(root *TreeNode) {
var first, second, pre = &TreeNode{Val: -1}, &TreeNode{Val: -1}, &TreeNode{Val: -1}
if root == nil || (root.Left == nil && root.Right == nil) {
return
}
inorder(root, &first, &second, &pre)
first.Val, second.Val = second.Val, first.Val
}
101. [LeetCode] Symmetric Tree 判断对称树
递归方法
func isSymmetric(root *TreeNode) bool {
if root == nil {
return true
}
return symmetric(root.Left, root.Right)
}
func symmetric(p, q *TreeNode) bool {
if p == nil && q == nil {
return true
}
if (p == nil && q != nil) || (p != nil && q == nil) || p.Val != q.Val {
return false
}
return symmetric(p.Left, q.Right) && symmetric(p.Right, q.Left)
}
102. Binary Tree Level Order Traversal 二叉树层序遍历
func levelOrder(root *TreeNode) [][]int {
var queue, res = list.New(), make([][]int, 0)
if root == nil {
return res
}
queue.PushBack(root)
for queue.Len() != 0 {
var n = queue.Len()
var temp = make([]int, n)
for i := 0; i < n; i++ {
var val = queue.Front()
var cur = val.Value.(*TreeNode)
queue.Remove(val)
if cur.Left != nil {
queue.PushBack(cur.Left)
}
if cur.Right != nil {
queue.PushBack(cur.Right)
}
temp[i] = cur.Val
}
res = append(res, temp)
}
return res
}
104. [LeetCode] Maximum Depth of Binary Tree 二叉树的最大深度
递归方法,从根结点到叶结点依次经过的结点形成树的一条路径,最长路径的长度为树的深度。
采用递归的方法,因为每个结点的这个子树的深度为,它的左右子树的深度中大的那一个加1,logn的时间复杂度,但是在树的深度过大时,会有栈溢出的问题
class Solution {
public:
int maxDepth(TreeNode *root) {
if (root == NULL)
return 0;
else {
int x1 = maxDepth(root->left) + 1;
int x2 = maxDepth(root->right) + 1;
return (x1 > x2 ? x1 : x2);
}
}
};
111. Minimum Depth of Binary Tree二叉树最小深度
func min(a, b int) int {
if a < b {return a}
return b
}
func minDepth(root *TreeNode) int {
if root == nil {return 0}
if root.Left == nil {return 1+minDepth(root.Right)}
if root.Right == nil {return 1+minDepth(root.Left)}
return 1 + min(minDepth(root.Left), minDepth(root.Right))
}
105. Construct Binary Tree from Preorder and Inorder Traversal先序和中序遍历建立二叉树
先序的顺序的第一个肯定是根,定位出根节点的位置,并以根节点的位置将中序遍历拆分为左右两个部分
func buildTree(preorder []int, inorder []int) *TreeNode {
return build(preorder, 0, len(preorder)-1, inorder, 0, len(inorder)-1)
}
func build(preorder []int, pl, pr int, inorder []int, il, ir int) *TreeNode {
if pl > pr || il > ir {return nil}
var pos = 0
for pos = il; pos <= ir; pos++ {
if preorder[pl] == inorder[pos] {break}
}
var cur = &TreeNode{Val: preorder[pl]}
cur.Left = build(preorder, pl+1, pl +pos-il, inorder, il, pos-1)
cur.Right = build(preorder, pl+pos-il+1, pr, inorder, pos+1, ir)
return cur
}
108. Convert Sorted Array to Binary Search Tree 将有序数组转为二叉搜索树
左<根<右,根节点应该是有序数组的中间点,从中间点分开为左右两个有序数组,在分别找出其中间点作为原中间点的左右两个子节点,二分查找
func sortedArrayToBST(nums []int) *TreeNode {
return sortedToBST(nums, 0, len(nums)-1)
}
func sortedToBST(nums []int, start, end int) *TreeNode {
if start > end {return nil}
var mid = (start + end) / 2
var root = &TreeNode{Val: nums[mid]}
root.Left = sortedToBST(nums, start, mid-1)
root.Right = sortedToBST(nums, mid+1, end)
return root
}
110. Balanced Binary Tree 平衡二叉树
func maxInt(a, b int) int {
if a > b {return a}
return b
}
func abs(a, b int) int {
if a > b {return a-b}
return b-a
}
func isBalanced(root *TreeNode) bool {
if root == nil {return true}
var left = height(root.Left)
var right = height(root.Right)
if abs(left, right) > 1 {return false}
return isBalanced(root.Left) && isBalanced(root.Right)
}
func height(root *TreeNode) int {
if root == nil {return 0}
return 1 + maxInt(height(root.Left), height(root.Right))
}
144. Binary Tree Preorder Traversal
递归方法
func preorderTraversal(root *TreeNode) []int {
var ret []int
return preorder(root, ret)
}
func preorder(root *TreeNode, ret []int) []int {
if root == nil {
return ret
}
ret = append(ret, root.Val)
ret = preorder(root.Left, ret)
return preorder(root.Right, ret)
}
非递归方法
func preorderTraversal(root *TreeNode) []int {
var ret []int
var stack = list.New()
var t = root
for t != nil || stack.Len() != 0 {
for t != nil {
ret = append(ret, t.Val)
stack.PushBack(t)
t = t.Left
}
if stack.Len() != 0 {
var val = stack.Back()
var curNode = val.Value.(*TreeNode)
t = curNode.Right
stack.Remove(val)
}
}
return ret
}
145. Binary Tree Postorder Traversal
后序遍历
递归方法
func postorderTraversal(root *TreeNode) []int {
var ret []int
return postorder(root, ret)
}
func postorder(root *TreeNode, ret []int) []int {
if root == nil {
return ret
}
ret = preorder(root.Left, ret)
ret = preorder(root.Right, ret)
ret = append(ret, root.Val)
return ret
}
非递归非方法
func postorderTraversal(root *TreeNode) []int {
var ret []int
var stack = list.New()
var pre *TreeNode
if root != nil {
stack.PushBack(root)
}
for stack.Len() != 0 {
val := stack.Back()
cur := val.Value.(*TreeNode)
if pre == nil || pre.Left == cur || pre.Right == cur {
if cur.Left != nil {
stack.PushBack(cur.Left)
} else if cur.Right != nil {
stack.PushBack(cur.Right)
}
} else if cur.Left == pre {
if cur.Right != nil {
stack.PushBack(cur.Right)
}
} else {
ret = append(ret, cur.Val)
stack.Remove(val)
}
pre = cur
}
return ret
}
129. [LeetCode] Sum Root to Leaf Numbers
func sumNumbers(root *TreeNode) int {
return sumTree(root, 0)
}
func sumTree(root *TreeNode, sum int) int {
if root == nil {
return sum
}
var curr = sum*10 + root.Val
if root.Left == nil && root.Right == nil {
return curr
}
var left, right = 0, 0
if root.Left != nil {
left = sumTree(root.Left, curr)
}
if root.Right != nil {
right = sumTree(root.Right, curr)
}
return left + right
}
递归到该点的时候就把这点的值与前面的值乘以10,然后相加
func sumNumbers(root *TreeNode) int {
return sumTree(root, 0)
}
func sumTree(root *TreeNode, sum int) int {
if root == nil {
return 0
}
var curr = sum*10 + root.Val
if root.Left == nil && root.Right == nil {
return curr
}
return sumTree(root.Left, curr) + sumTree(root.Right, curr)
}
递归方法
func isSameTree(p *TreeNode, q *TreeNode) bool {
if p == nil && q == nil {
return true
}
if (p == nil && q != nil) || (p != nil && q == nil) || p.Val != q.Val {
return false
}
return isSameTree(p.Left, q.Left) && isSameTree(p.Right, q.Right)
}
112. Path Sum 二叉树的路径和
深度优先算法DFS的思想来遍历每一条完整的路径,也就是利用递归不停找子节点的左右子节点,而调用递归函数的参数只有当前节点和sum值。
func hasPathSum(root *TreeNode, sum int) bool {
if root == nil {
return false
}
if root.Left == nil && root.Right == nil && root.Val == sum {
return true
}
return hasPathSum(root.Left, sum - root.Val) || hasPathSum(root.Right, sum - root.Val)
}
113. Path Sum II
每当DFS搜索到新节点时,都要保存该节点。而且找出一条路径之后,保存到最终结果二位vector中。每当DFS搜索到子节点,发现不是路径和时,返回上一个结点时,需要把该节点从一维vector中移除
func pathSum(root *TreeNode, sum int) [][]int {
var cur = make([]int, 0)
var ret [][]int
path(root, sum, cur, &ret)
return ret
}
func path(root *TreeNode, sum int, cur []int, ret *[][]int) {
if root == nil {
return
}
cur = append(cur, root.Val)
if sum == root.Val && root.Left == nil && root.Right == nil {
res := make([]int, len(cur))
copy(res, cur)
*ret = append(*ret, res)
}
path(root.Left, sum-root.Val, cur, ret)
path(root.Right, sum-root.Val, cur, ret)
if len(cur) > 0 {
cur = cur[:len(cur)-1]
}
}
226. Invert Binary Tree
func invertTree(root *TreeNode) *TreeNode {
if root == nil {
return nil
}
var temp = root.Left
root.Left = invertTree(root.Right)
root.Right = invertTree(temp)
return root
}
404. Sum of Left Leaves
求一棵二叉树的所有左子叶的和,需要知道当前结点是否是左子节点,如果是左子节点,而且该左子节点再没有子节点了说明其是左子叶,那么我们将其值加入结果res中,我们用一个bool型的变量,如果为true说明当前结点是左子节点,若为false则说明是右子节点,不处理
func sumOfLeftLeaves(root *TreeNode) int {
if root == nil || (root.Left==nil && root.Right==nil) {
return 0
}
var ret = 0
sumLeft(root.Left, true, &ret)
sumLeft(root.Right, false, &ret)
return ret
}
func sumLeft(root *TreeNode, left bool, ret *int) {
if root == nil {
return
}
if left && root.Left == nil && root.Right == nil {
*ret += root.Val
}
sumLeft(root.Left, true, ret)
sumLeft(root.Right, false, ret)
}
572. Subtree of Another Tree
从s的根结点开始,跟t比较,如果两棵树完全相同,那么返回true,否则就分别对s的左子结点和右子结点调用递归再次来判断是否相同
func isSubtree(s *TreeNode, t *TreeNode) bool {
if s == nil {
return false
}
if isSameTree(s, t) {
return true
}
return isSubtree(s.Left, t) || isSubtree(s.Right, t)
}
func isSameTree(s *TreeNode, t *TreeNode) bool {
if s == nil && t == nil {
return true
}
if (s == nil && t != nil) || (s != nil && t == nil) || s.Val != t.Val {
return false
}
return isSameTree(s.Left, t.Left) && isSameTree(s.Right, t.Right)
}
700. Search in a Binary Search Tree
左<根<右。那么就是说任意一个结点的左子树中的所有结点均小于当前结点,其右子树中的所有结点均大于当前结点
func searchBST(root *TreeNode, val int) *TreeNode {
if root == nil {
return nil
}
if root.Val == val {
return root
} else if root.Val > val{
return searchBST(root.Left, val)
} else {
return searchBST(root.Right, val)
}
}
235. Lowest Common Ancestor of a Binary Search Tree
func lowestCommonAncestor(root, p, q *TreeNode) *TreeNode {
if root == nil {
return nil
}
min := func(one, two int) int {
if one < two {
return one
}
return two
}
max := func(one, two int) int {
if one > two {
return one
}
return two
}
if root.Val < min(p.Val, q.Val) {
return lowestCommonAncestor(root.Right, p, q)
} else if root.Val > max(p.Val, q.Val) {
return lowestCommonAncestor(root.Left, p, q)
} else {
return root
}
}
236. Lowest Common Ancestor of a Binary Tree
当前结点是否为空,或者为p或q中的任意一个
若p和q要么分别位于左右子树中,那么对左右子结点调用递归函数,会分别返回p和q结点的位置
func lowestCommonAncestor(root, p, q *TreeNode) *TreeNode {
if root == nil || p == root || q == root {
return root
}
var left = lowestCommonAncestor(root.Left, p, q)
var right = lowestCommonAncestor(root.Right, p, q)
if left != nil && right != nil {
return root
}
if left != nil {
return left
}
return right
}
1. 判断一个树是否平衡二叉树
如果某个二叉树中任意结点的左右子树的深度相差不超过1,那么他就是一棵平衡二叉树。
首先可以采用递归的方法来计算每一个结点的深度,需要递归计算它的左右子树的深度,当返回的左右的子树的深度差大于1时就不是平衡二叉树了。
int highTree(TreeNode* root) {
if(root==NULL) return 0;
int L=0, R=0;
if(root->left)
L=highth(root->left);
if(root->right)
R=highth(root->right);
if(L-R>1||R-L>1)
flag=0;
return max(L,R)+1;
}