zoukankan      html  css  js  c++  java
  • 二叉搜索树与递归

    二叉搜索树与递归----以LeetCode题目为例

    首先,BST 的特性:

    1、对于 BST 的每一个节点node,左子树节点的值都比node的值要小,右子树节点的值都比node的值大。

    2、对于 BST 的每一个节点node,它的左侧子树和右侧子树都是 BST。

    二叉搜索树并不算复杂,但我觉得它构建起了数据结构领域的半壁江山,直接基于 BST 的数据结构有 AVL 树,红黑树等等,拥有了自平衡性质,可以提供 logN 级别的增删查改效率;还有 B+ 树,线段树等结构都是基于 BST 的思想来设计的。

    从做算法题的角度来看 BST,除了它的定义,还有一个重要的性质:BST 的中序遍历结果是有序的(升序)

    也就是说,如果输入一棵 BST,以下代码可以将 BST 中每个节点的值升序打印出来:

    1 void traverse(TreeNode root) {
    2     if (root == null) return;
    3     traverse(root.left);
    4     // 中序遍历代码位置
    5     print(root.val);
    6     traverse(root.right);
    7 }

    230. 二叉搜索树中第K小的元素

     中序遍历便是递增顺序,然后k位置输出

     1 # Definition for a binary tree node.
     2 # class TreeNode:
     3 #     def __init__(self, val=0, left=None, right=None):
     4 #         self.val = val
     5 #         self.left = left
     6 #         self.right = right
     7 class Solution:
     8     def kthSmallest(self, root: TreeNode, k: int) -> int:
     9         ans=[]
    10         def traverse(root):
    11             if root==None:
    12                 return 
    13             traverse(root.left)
    14             ans.append(root.val)
    15             traverse(root.right)
    16         traverse(root)
    17         return ans[k-1]

    感觉下面这种写法,复杂度应该更低呀,不知道为什么运行时间比上面还长

     1 # Definition for a binary tree node.
     2 # class TreeNode:
     3 #     def __init__(self, val=0, left=None, right=None):
     4 #         self.val = val
     5 #         self.left = left
     6 #         self.right = right
     7 class Solution:
     8     def kthSmallest(self, root: TreeNode, k: int) -> int:
     9         def traverse(root):
    10             nonlocal ans,res
    11             if root==None:
    12                 return 
    13             traverse(root.left)
    14             ans+=1
    15             if ans==k:
    16                 res=root.val
    17                 return 
    18             traverse(root.right)
    19         ans,res=0,-1
    20         traverse(root)
    21         return res

    Leetcode 235. 二叉搜索树的最近公共祖先

     第一种,解题方法就是寻找p、q的路径,两个路径第一次相同时就是最近公共祖先

     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 lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
    10         def path(node, t):
    11             p=[]
    12             while node!=t:
    13                 p.append(node)
    14                 if t.val<node.val:
    15                     node=node.left
    16                 elif t.val>node.val:
    17                     node=node.right
    18             p.append(node)
    19             return p
    20 
    21         p1=path(root,p)
    22         p2=path(root,q)
    23         ans=None
    24         for u,v in zip(p1,p2):
    25             if u==v:
    26                 ans=u
    27             else:
    28                 break
    29         return ans

     这种方法,需要动下脑子,参考作者sdwwld的写法,就是

    如果两个节点值都小于根节点,说明他们都在根节点的左子树上,我们往左子树上找
    如果两个节点值都大于根节点,说明他们都在根节点的右子树上,我们往右子树上找
    如果一个节点值大于根节点,一个节点值小于根节点,说明他们他们一个在根节点的左子树上一个在根节点的右子树上,那么根节点就是他们的最近公共祖先节点。

     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 lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
    10         # 如果小于等于0,说明p和q位于root的两侧,直接返回即可
    11         if ((root.val - p.val) * (root.val - q.val) <= 0):
    12             return root
    13         #否则,p和q位于root的同一侧,就继续往下找
    14         if p.val<root.val:
    15             return self.lowestCommonAncestor(root.left, p, q)
    16         else:
    17             return self.lowestCommonAncestor(root.right, p, q)
  • 相关阅读:
    个人笔记 给hover 伪类 恢复默认值
    vue 正则判断
    音乐播放器封装
    jq封装插件,简单dome
    功能齐全轮播
    vue 前端判断输入框不能输入0 空格。特殊符号。
    jq 下拉框
    IPC : 进程间通信方式
    内存
    const char* str 与char str[10]
  • 原文地址:https://www.cnblogs.com/z-712/p/14810541.html
Copyright © 2011-2022 走看看