算法攻略(树 、二叉树、二叉搜索树)

1.知识点

  • 树:
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
Linked List 就是特殊化的 Tree
Tree 就是特殊化的 Graph

在这里插入图片描述

特点:

二叉搜索树(英语:Binary Search Tree),也称二叉搜索树、有
序二叉树(英语:ordered binary tree),排序二叉树(英语:
sorted binary tree),是指⼀一棵空树或者具有下列列性质的二叉树:
1. 若任意节点的左⼦子树不不空,则左⼦子树上所有结点的值均小于它的根结点的值;
2. 若任意节点的右⼦子树不不空,则右⼦子树上所有结点的值均⼤大于它的根结点的值;
3. 任意节点的左、右⼦子树也分别为⼆二叉查找树。

在这里插入图片描述

  • python 定义二叉树
    eg:
    在这里插入图片描述

  • sort list with key
    在这里插入图片描述

2 代码实战

实战题⽬目
1. https://leetcode.com/problems/validate-binary-search-tree
2. https://leetcode.com/problems/lowest-common-ancestorof-
a-binary-search-tree/
3. https://leetcode.com/problems/lowest-common-ancestorof-
a-binary-tree/

2.1 Validate Binary Search Tree

98. Validate Binary Search Tree

  • 方法一(python判重、排序):较低效
class Solution:
    def isValidBST(self, root):
        inorder = self.inorder(root)
        print("中序遍历:{}".format(inorder))
        print("排序:{}".format(list(sorted(set(inorder)))))
        return inorder == list(sorted(set(inorder)))
    def inorder(self,root):
        if root is None:
            return []
        return self.inorder(root.left) + [root.value] + self.inorder(root.right)
class Node:  
    def __init__(self,value=None,left=None,right=None):  
         self.value=value  
         self.left=left    #左子树
         self.right=right  #右子树
root1=Node('D',Node('B',Node('A'),Node('C')),Node('E',right=Node('G',Node('Y'))))
root2=Node('D',Node('B',Node('A'),Node('C')),Node('E',right=Node('G',Node('F'))))
solu = Solution()
solu.isValidBST(root1)

结果:

中序遍历:['A', 'B', 'C', 'D', 'E', 'Y', 'G']
排序:['A', 'B', 'C', 'D', 'E', 'G', 'Y']
False

-前继节点法:节省内存


在这里插入图片描述

2.2 Kth Largest Element in a Stream

703. Kth Largest Element in a Stream
在这里插入图片描述
在这里插入图片描述
利用优先队列中,最小堆的算法,可将时间复杂度降低。上图所示,k*log(k)是快排的时间复杂度,log(2)k是Min Heap的时间复杂度。
C++代码:

class KthLargest {
public:
    KthLargest(int k, vector<int>& nums) {
        int i;
        kth = k;
        //将arr中前k个数据放入优先队列中,排序,最小的数在队头
        for ( i = 0; i < k && i < nums.size(); i++ )
            q.push(nums[i]);
        //维护具有k个元素的小顶堆.
        while(i < nums.size()) {
            if (nums[i] > q.top() ) {
                q.pop();
                q.push(nums[i]);
            }
            i++;
        }
    }
    
    int add(int val) {
        int k;
        //如果堆为空或者堆长小于k,则继续向堆中加入数据
        if (q.empty() || q.size() < kth ) {
            q.push(val);
        } else {
            k = q.top();          //找到堆顶元素,即堆中最小的数
            if (val > k ) {       //和实时传来的数做比较,维护小顶堆
                q.pop();
                q.push(val);
            }
        }
        return q.top();     //如果传过来的数比推顶的数小,则舍弃,返回原堆顶的数即可
    }
    private :
        priority_queue<int,vector<int>,greater<int>> q;
        int kth;
};
/**
 * Your KthLargest object will be instantiated and called as such:
 * KthLargest* obj = new KthLargest(k, nums);
 * int param_1 = obj->add(val);
 */

在这里插入图片描述
在这里插入图片描述

2.3 Sliding Window Maximum

239. Sliding Window Maximum
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
此题中,不用优先队列。因为窗口中只要维护最大值即可,不用维护第二大,第三大的值,所以算法可以加速,采用双端队列的方法。

在这里插入图片描述
维护队列左边最大。

class Solution:
    def maxSlidingWindow(self, nums: List[int], k: int) -> List[int]:
        //判断输入是否合法
        if not nums : return []
        //初始化window和存放结果的列表
        window, res = [], []
        for i, x in enumerate(nums):
            //维护窗口大小为k
            if i >= k and window[0] <= i - k:
                window.pop(0)
            //将左侧比当前x值小的数据索引都清掉,维护左端最大
            while window and nums[window[-1]] <= x:
                window.pop()
            window.append(i)
            //将最大值放入res列表中
            if i >= k-1:
                res.append(nums[window[0]])
        return res

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值