zoukankan      html  css  js  c++  java
  • 面试题54:二叉搜索树的第k大节点(C++)

    题目地址:https://leetcode-cn.com/problems/er-cha-sou-suo-shu-de-di-kda-jie-dian-lcof/

    题目描述

    给定一棵二叉搜索树,请找出其中第k大的节点。

    题目示例

    示例 1:

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

      2
    输出: 4
    示例 2:

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

    解题思路

    图源(https://leetcode-cn.com/problems/er-cha-sou-suo-shu-de-di-kda-jie-dian-lcof/solution/mian-shi-ti-54-er-cha-sou-suo-shu-de-di-k-da-jie-d/)

    分析题目我们可以发现,二叉搜索树的中序遍历(左子树、根节点、右子树)为单调递增的序列,求二叉搜索树的第k大节点,等同于求二叉搜索树中序遍历的倒序的第k个节点,而二叉搜索树的倒序遍历(右子树、根节点、左子树)为单调递减序列。因为题目已知的是二叉搜索树,所以默认是已经排好序的,如果要求二叉树的第k大节点?那么如何做呢,通常的做法是利用二叉树中序遍历的有序性,将遍历的值存储在数组中,然后输出倒数第k个元素。当然,还有另一种经典方法就是使用优先队列实现大顶堆和小顶堆的方法。

    优先队列默认是大顶堆,符合题目要求,所以我们通过深度优先搜索方法,将树中所有的节点的值加入优先队列(默认大顶堆)中,然后弹出优先队列中前k-1个元素,最后,队首元素即为所求值。

    程序源码

    递归

    /**
     * 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 cnt = 0;
        int res_num = 0;
        int kthLargest(TreeNode* root, int k) {
            dfs(root,k);
            return res_num;
        }
        void dfs(TreeNode* root, int k)
        {
            if(root == nullptr) return ;
            dfs(root->right, k);
            cnt++;
            if(cnt == k)
            res_num = root->val;
            dfs(root->left, k);
    
    
        }
    };

    迭代(栈)

    /**
     * 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 cnt = 0; //维护一个计数器
        int kthLargest(TreeNode* root, int k) {
            if(root == nullptr) return 0;
            TreeNode* p = root;
            stack<TreeNode*> s;
            s.push(p);
            while(p || !s.empty())
            {
                while(p)
                {
                    s.push(p);
                    p = p->right;
                }
                p = s.top();
                s.pop();
                cnt++;
                if(cnt == k) return p->val;
                p = p->left;
            }
            return 0;
        }
    };

    大顶堆(优先队列)

    /**
     * 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:
        priority_queue<int> prior_que;
        void dfs(TreeNode* root)
        {
            prior_que.push(root->val);
            if(root->left != nullptr) dfs(root->left);
            if(root->right != nullptr) dfs(root->right);
        }
        int kthLargest(TreeNode* root, int k) {
            dfs(root);
            while(--k)
            {
                prior_que.pop();
            }
            return prior_que.top();
    };

    二叉树求倒数第k大节点(非二叉搜索树,即无序)

    /**
     * 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 kthLargest(TreeNode* root, int k) {
        
         vector<int> res;
         stack<TreeNode*> s;
         TreeNode* p;
         p = root;
         while(p!=NULL || !s.empty())
         {
             while(p != NULL)
             {
                 s.push(p);
                 p=p->left;
             }
             if(!s.empty())
             {
                 p = s.top();
                 s.pop();
                 res.push_back(p->val);
                 p = p->right;
             }
         }
         return res[res.size() - k];
        }
    };
    ----------------------------------- 心之所向,素履所往;生如逆旅,一苇以航。 ------------------------------------------
  • 相关阅读:
    redis发布订阅
    redis学习笔记(面试题)
    redis安全 (error) NOAUTH Authentication required
    HDU3001 Travelling —— 状压DP(三进制)
    POJ3616 Milking Time —— DP
    POJ3186 Treats for the Cows —— DP
    HDU1074 Doing Homework —— 状压DP
    POJ1661 Help Jimmy —— DP
    HDU1260 Tickets —— DP
    HDU1176 免费馅饼 —— DP
  • 原文地址:https://www.cnblogs.com/wzw0625/p/12677838.html
Copyright © 2011-2022 走看看