• 二叉搜索树中第K小的元素-- 二分查找


    题目

    给定一个二叉搜索树,编写一个函数 kthSmallest 来查找其中第 k 个最小的元素。

    说明:
    你可以假设 k 总是有效的,1 ≤ k ≤ 二叉搜索树元素个数。

    示例 1:

    输入: root = [3,1,4,null,2], k = 1
       3
      / 
     1   4
      
       2
    输出: 1

    示例 2:

    输入: root = [5,3,6,2,4,null,null,1], k = 3
           5
          / 
         3   6
        / 
       2   4
      /
     1
    输出: 3

    进阶:
    如果二叉搜索树经常被修改(插入/删除操作)并且你需要频繁地查找第 k 小的值,你将如何优化 kthSmallest 函数?

    前序

    首先了解一下二叉搜索树.

    二叉搜索树(Binary Search Tree)是指一颗空树或者具有下列性质的二叉树

    • 任意节点的左子树不空,则左子树上所有结点的值均小于它的根结点的值;

    • 任意节点的右子树不空,则右子树上所有结点的值均大于它的根结点的值;

    • 任意节点的左、右子树也分别为二叉查找树;

    • 没有键值相等的节点。

    二叉搜索树有一个有一个重要的性质, 中序遍历为排序数组,也就是从小到大排序

    1. 查找 BST 中的某个元素

    在二叉搜索树b中查找x的过程为:

    1. 若b是空树,则搜索失败,否则:

    2. 若x等于b的根节点的数据域之值,则查找成功;否则:

    3. 若x小于b的根节点的数据域之值,则搜索左子树;否则:

    4. 查找右子树。

    2. 从有序数组构造一个二叉查找树

     3. 往 BST 中插入元素

    向一个二叉搜索树b中插入一个节点s的算法,过程为:

    1. 若b是空树,则将s所指结点作为根节点插入,否则:

    2. 若s->data等于b的根节点的数据域之值,则返回,否则:

    3. 若s->data小于b的根节点的数据域之值,则把s所指节点插入到左子树中,否则:

    4. 把s所指节点插入到右子树中。(新插入节点总是叶子节点)

    通过上面的前续,了解了二叉搜索树的基本内容和性质, 下面我们着重解决本题目!!!


    思想 与 解法

    1. 二分法

    思想

    二叉搜索树特点是左节点值小于根节点,而右节点值大于根节点;利用这个特性可以采用二分法,将整个树的节点分为左节点和右节点两部分,当k值等于左节点值+1时,说明此时root为要求的第k小元素;当k值小于左节点值时,说明第k小元素位于根节点左侧;当k值大于左节点时,说明第k小元素位于根节点右侧;之后递归,在满足条件的左右两侧节点中进行遍历划分,直到求出第k小。

    代码

    public class TreeNode {
        public var val: Int
        public var left: TreeNode?
        public var right: TreeNode?
        public init(_ val: Int){
            self.val = val
            self.left = nil
            self.right = nil
        }
    }
    
    func kthSmallest(_ root: TreeNode?, _ k: Int) -> Int {
        let left_num = calculate(root?.left)
        if k - 1 == left_num {
            return root?.val ?? 0
        } else if k - 1 < left_num {
            return kthSmallest(root?.left, k)
        } else {
            return kthSmallest(root?.right, k - 1 - left_num)
        }
    }
    
    func calculate(_ root: TreeNode?) -> Int {
        if root == nil {
            return 0
        }
        let num = 1 + calculate(root?.left) + calculate(root?.right)
        return num
    }

    2. 中序排序(递归)

    二叉搜索树特点是左节点值小于根节点,而右节点值大于根节点;当我们进行中序遍历时【左中右】,就可以将整个二叉搜索树按照从小到大的顺序进行遍历,使用一个计数器,当与k值相等时,就可以输出当前节点元素。
    public:
        int kthSmallest(TreeNode* root, int k) { //利用中序遍历进行计数
            int num = 0;
            int res = 0;
            Inorder(root,k,num,res);
            return res;
        }//中序遍历(左中右)
        void Inorder(TreeNode* root,int k,int &num,int &res){
            if(root == NULL)
            {
                return ;
            }
            Inorder(root->left,k,num,res);
            num++;
            if(k == num)
            {
                res = root->val;
            }
            Inorder(root->right,k,num,res);
        }

    3. 中序排序(栈)

    原理同样是中序遍历,但是结合了栈进行了操作,降低了递归引起的效率低的问题

    /**
     * Definition for a binary tree node.
     * struct TreeNode {
     *     int val;
     *     TreeNode *left;
     *     TreeNode *right;
     *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
     * };
     */
    class Solution {
    public:
        int kthSmallest(TreeNode *root, int k)
        {
            stack<TreeNode *> s;
            while (1)
            {
                if (root)
                {
                    s.push(root);
                    root = root->left;
                    continue;
                }
                if (k == 1)
                    return s.top()->val;
                root = s.top()->right;
                s.pop();
                k--;
            }
        }
    };

    以上就是二叉搜索树第k小元素的求解过程!!!

     
  • 相关阅读:
    02点睛Spring4.1-Java Config
    01点睛Spring4.1-依赖注入
    00点睛Spring4.1-环境搭建
    Cas(09)——通过Proxy访问其它Cas应用
    Cas(08)——单点登出
    Cas(07)——建立使用Cas进行单点登录的应用
    Cas(06)——基于数据库的认证
    Cas(05)——修改Cas Server的其它配置
    remove CMakeCache.txt and rerun cmake.On Debian/Ubuntu, package name is libncurses5-dev, on Redhat and derivates it is ncurses-devel.
    解放双手—Cobbler批量自动化部署多版本系统
  • 原文地址:https://www.cnblogs.com/guohai-stronger/p/12118232.html
Copyright © 2020-2023  润新知