当前位置:   article > 正文

LeetCode--二叉搜索树_建立 二叉搜索树 leetcode

建立 二叉搜索树 leetcode

LeetCode98. Validate Binary Search Tree验证二叉搜索树

一、题目

给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。

有效 二叉搜索树定义如下:

节点的左子树只包含 小于 当前节点的数。
节点的右子树只包含 大于 当前节点的数。
所有左子树和右子树自身必须也是二叉搜索树。

示例 1:

输入:root = [2,1,3]
输出:true
示例 2:

输入:root = [5,1,4,null,null,3,6]
输出:false
解释:根节点的值是 5 ,但是右子节点的值是 4 。

提示:

树中节点数目范围在[1, 104] 内
-231 <= Node.val <= 231 - 1

二、解决方法

方法一:递归

//  递归
//  根节点是左子树的上限,是右子树的下限
//  时间复杂度O(n),空间复杂度O(n)
  1. func main() {
  2. root := &TreeNode{Val: 5, Left: &TreeNode{4, initTreeNode(1), initTreeNode(7)}, Right: initTreeNode(8)}
  3. fmt.Println(root)
  4. fmt.Println(isValidBST(root))
  5. }
  6. type TreeNode struct {
  7. Val int
  8. Left *TreeNode
  9. Right *TreeNode
  10. }
  11. func initTreeNode(val int) *TreeNode {
  12. return &TreeNode{Val: val, Left: nil, Right: nil}
  13. }
  14. // 递归
  15. func isValidBST(root *TreeNode) bool {
  16. return recurse(root, math.MinInt64, math.MaxInt64)
  17. }
  18. func recurse(root *TreeNode, lower, higher int) bool {
  19. if root == nil {
  20. return true
  21. }
  22. if root.Val <= lower || root.Val >= higher {
  23. return false
  24. }
  25. return recurse(root.Left, lower, root.Val) && recurse(root.Right, root.Val, higher)
  26. }

方法二:中序遍历

// 中序遍历
// 二叉搜索树「中序遍历」得到的值构成的序列一定是升序的
//  时间复杂度O(n),空间复杂度O(n)
  1. func isValidBST2(root *TreeNode) bool {
  2. stack := []*TreeNode{}
  3. inorder := math.MinInt64
  4. for len(stack) > 0 || root != nil {
  5. for root != nil {
  6. stack = append(stack, root)
  7. // 左
  8. root = root.Left
  9. }
  10. // 从栈取值
  11. root = stack[len(stack)-1]
  12. stack = stack[:len(stack)-1]
  13. // 如果比上一个节点小,则false
  14. if root.Val <= inorder {
  15. return false
  16. }
  17. inorder = root.Val
  18. // 右
  19. // 不用加入栈中,因为会在循环一开始的时候就先加入栈
  20. root = root.Right
  21. }
  22. return true
  23. }

LeetCode99. Recover Binary Search Tree恢复二叉搜索树

todo

好难


LeetCode100. Same Tree相同的树

一、题目

给你两棵二叉树的根节点 p 和 q ,编写一个函数来检验这两棵树是否相同。

如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。



示例 1:


输入:p = [1,2,3], q = [1,2,3]
输出:true
示例 2:


输入:p = [1,2], q = [1,null,2]
输出:false
示例 3:


输入:p = [1,2,1], q = [1,1,2]
输出:false


提示:

两棵树上的节点数目都在范围 [0, 100] 内
-104 <= Node.val <= 104

二、解决方法

// dfs递归
// 时间复杂度o(min(m,n)), 空间复杂度o(min(m,n))
  1. func main() {
  2. p := &TreeNode{Val: 1, Left: &TreeNode{3, nil, initTreeNode(2)}, Right: nil}
  3. q := &TreeNode{Val: 1, Left: &TreeNode{3, nil, initTreeNode(2)}, Right: nil}
  4. fmt.Println(preorderTraversal(p))
  5. fmt.Println(preorderTraversal(q))
  6. fmt.Println(isSameTree(p, q))
  7. }
  8. type TreeNode struct {
  9. Val int
  10. Left *TreeNode
  11. Right *TreeNode
  12. }
  13. func initTreeNode(val int) *TreeNode {
  14. return &TreeNode{Val: val, Left: nil, Right: nil}
  15. }
  16. func preorderTraversal(root *TreeNode) []int {
  17. res := []int{}
  18. dfs(&res, root)
  19. return res
  20. }
  21. func dfs(res *[]int, root *TreeNode) {
  22. if root == nil {
  23. return
  24. }
  25. *res = append(*res, root.Val)
  26. dfs(res, root.Left)
  27. dfs(res, root.Right)
  28. }
  29. // dfs
  30. // 时间复杂度o(min(m,n)), 空间复杂度o(min(m,n))
  31. func isSameTree(p *TreeNode, q *TreeNode) bool {
  32. if p == nil && q == nil {
  33. return true
  34. }
  35. if p != nil && q == nil || p == nil && q != nil {
  36. return false
  37. }
  38. return p.Val == q.Val && isSameTree(p.Left, q.Left) && isSameTree(p.Right, q.Right)
  39. }


LeetCode102.Binary Tree Level Order Traversal二叉树的层序遍历

一、题目

给你二叉树的根节点 root ,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。

示例 1:

输入:root = [3,9,20,null,null,15,7]
输出:[[3],[9,20],[15,7]]
示例 2:

输入:root = [1]
输出:[[1]]
示例 3:

输入:root = []
输出:[]

提示:

树中节点数目在范围 [0, 2000] 内
-1000 <= Node.val <= 1000

二、解决方法

方法一:bfs

// bfs,双队列两层循环
// 为了好找到位置加了level作为下标
// 时间复杂度o(n), 空间复杂度o(n)
  1. func main() {
  2. root := &TreeNode{Val: 3, Left: &TreeNode{9, initTreeNode(10), initTreeNode(11)},
  3. Right: &TreeNode{20, initTreeNode(12), initTreeNode(17)}}
  4. fmt.Println(levelOrder(root))
  5. }
  6. type TreeNode struct {
  7. Val int
  8. Left *TreeNode
  9. Right *TreeNode
  10. }
  11. func initTreeNode(val int) *TreeNode {
  12. return &TreeNode{Val: val, Left: nil, Right: nil}
  13. }
  14. // bfs,双队列
  15. func levelOrder(root *TreeNode) (res [][]int) {
  16. if root == nil {
  17. return
  18. }
  19. q := []*TreeNode{root}
  20. // 为了好找到位置加了level作为下标
  21. level := 0
  22. for len(q) > 0 {
  23. res = append(res, []int{})
  24. p := []*TreeNode{}
  25. for len(q) > 0 {
  26. node := q[0]
  27. q = q[1:]
  28. if node.Left != nil {
  29. p = append(p, node.Left)
  30. }
  31. if node.Right != nil {
  32. p = append(p, node.Right)
  33. }
  34. res[level] = append(res[level], node.Val)
  35. }
  36. level++
  37. q = p
  38. }
  39. return
  40. }


LeetCode104.Maximum Depth of Binary Tree二叉树的最大深度

一、题目

给定一个二叉树,找出其最大深度。

二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。

说明: 叶子节点是指没有子节点的节点。

示例:
给定二叉树 [3,9,20,null,null,15,7],

    3
   / \
  9  20
    /  \
   15   7
返回它的最大深度 3 。

二、解决方法

方法一:dfs

// 时间复杂度O(N),空间复杂度O(height),取决于树的高度

方法二:bfs 

// 时间复杂度O(N),空间复杂度O(n)
  1. func main() {
  2. root := &TreeNode{Val: 3, Left: &TreeNode{9, nil, nil},
  3. Right: &TreeNode{20, initTreeNode(12), initTreeNode(17)}}
  4. fmt.Println(maxDepth2(root))
  5. }
  6. type TreeNode struct {
  7. Val int
  8. Left *TreeNode
  9. Right *TreeNode
  10. }
  11. func initTreeNode(val int) *TreeNode {
  12. return &TreeNode{Val: val, Left: nil, Right: nil}
  13. }
  14. // dfs
  15. // 时间复杂度O(N),空间复杂度O(height),取决于树的高度
  16. func maxDepth(root *TreeNode) (depth int) {
  17. if root == nil {
  18. return 0
  19. }
  20. return max(maxDepth(root.Left), maxDepth(root.Right)) + 1
  21. }
  22. func max(a, b int) int {
  23. if a > b {
  24. return a
  25. }
  26. return b
  27. }
  28. // bfs
  29. // 时间复杂度O(N),空间复杂度O(n)
  30. func maxDepth2(root *TreeNode) (depth int) {
  31. if root == nil {
  32. return 0
  33. }
  34. q := []*TreeNode{root}
  35. for len(q) > 0 {
  36. p := []*TreeNode{}
  37. depth++
  38. for len(q) > 0 {
  39. node := q[0]
  40. q = q[1:]
  41. if node.Left != nil {
  42. p = append(p, node.Left)
  43. }
  44. if node.Right != nil {
  45. p = append(p, node.Right)
  46. }
  47. }
  48. q = p
  49. }
  50. return depth
  51. }

Leetcode108.Convert Sorted Array to Binary Search Tree将有序数组转换为二叉搜索树

一、题目

给你一个整数数组 nums ,其中元素已经按 升序 排列,请你将其转换为一棵 高度平衡 二叉搜索树。

高度平衡 二叉树是一棵满足「每个节点的左右两个子树的高度差的绝对值不超过 1 」的二叉树。



示例 1:


输入:nums = [-10,-3,0,5,9]
输出:[0,-3,9,-10,null,5]
解释:[0,-10,5,null,-3,null,9] 也将被视为正确答案:

示例 2:


输入:nums = [1,3]
输出:[3,1]
解释:[1,3] 和 [3,1] 都是高度平衡二叉搜索树。


提示:

1 <= nums.length <= 104
-104 <= nums[i] <= 104
nums 按 严格递增 顺序排列

 二、解决办法

方法一:分治

  1. func main() {
  2. nums := []int{-10, -3, 0, 5, 9}
  3. root := sortedArrayToBST(nums)
  4. fmt.Println(preorderTraversal(root))
  5. }
  6. type TreeNode struct {
  7. Val int
  8. Left *TreeNode
  9. Right *TreeNode
  10. }
  11. func preorderTraversal(root *TreeNode) []int {
  12. res := []int{}
  13. dfs(&res, root)
  14. return res
  15. }
  16. func dfs(res *[]int, root *TreeNode) {
  17. if root == nil {
  18. return
  19. }
  20. *res = append(*res, root.Val)
  21. dfs(res, root.Left)
  22. dfs(res, root.Right)
  23. }
  24. // 分治法
  25. // 时间复杂度o(n), 空间复杂度o(logn)
  26. func sortedArrayToBST(nums []int) *TreeNode {
  27. l, r := 0, len(nums)-1
  28. return constructTree(nums, l, r)
  29. }
  30. func constructTree(nums []int, l, r int) *TreeNode {
  31. if l > r {
  32. return nil
  33. }
  34. mid := (l + r) >> 1
  35. node := &TreeNode{Val: nums[mid], Left: constructTree(nums, l, mid-1), Right: constructTree(nums, mid+1, r)}
  36. return node
  37. }

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/正经夜光杯/article/detail/818574?site
推荐阅读
相关标签
  

闽ICP备14008679号