A - The kth great number HDU - 4006(set+vector+优先队列)

题目传送:走你~

题意简介:写下很多很多的数,当遇到Q时输出第k大的数。

分析:很多很多的数,则开数组行不通,需要STL。输出第k大的数,则需要对原数据进行排序。如果强行暴力排序则会T掉,

而且用set时需要注意的一点是,set自动忽略相同的数,而根据题意需要相同的数这里用到了multiset.

法一:multiset

#include<iostream>
#include<cstdio>
#include<vector>
#include<set>
#include<algorithm>
using namespace std;
const int maxn = 1000100;

multiset<int> se;
int n, k, a, b;
char ch;
multiset<int>::iterator it;
int main()
{
    while(scanf("%d%d", &n, &k) != EOF)
    {
        se.clear(); // **不要忘记
        a = 0;
        for(int i = 0; i < n; i++)
        {
            getchar();
            ch = getchar();
            if(ch == 'I')
            {
                scanf("%d", &b);
                se.insert(b);
                a++;
                it = se.begin();
                if(se.size() > k) // 对set中数据进行维护,使他最多存有3个。
                    se.erase(it);
            }
            else
            {

                it = se.begin();
                printf("%d\n",*it);
            }

        }
    }
    return 0;
}

法二:优先队列

#include<bits/stdc++.h>
using namespace std;

int n, k, d;
char ch;
int main()
{
    while(scanf("%d%d", &n, &k) != EOF)
    {
        //其实和set很相似,简单的是方便维护最多3个数的队列
        priority_queue<int, vector<int>, greater<int> > pre;
        while(n--)
        {
            cin >> ch;
            if(ch == 'I')
            {
                scanf("%d", &d);
                pre.push(d);
                if(pre.size() > k)
                    pre.pop();
            }
            else
            {
                printf("%d\n", pre.top());
            }
        }

    }
    return 0;
}

法三:vector+查找插入,使其在输入时本身就有序。

#include<bits/stdc++.h>
using namespace std;

int n, k, d;
vector <int> vec;
char ch;
int main()
{
    while(scanf("%d%d", &n, &k) != EOF)
    {
        vec.clear();
        while(n--)
        {
            cin >> ch;
            if(ch == 'I')
            {
                scanf("%d", &d);
                int pos = lower_bound(vec.begin(), vec.end(), d) - vec.begin();
                vec.insert(vec.begin() + pos, d);
            }
            else
            {
                printf("%d\n", vec[vec.size() - k]);
            }
        }

    }
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 这道题目需要在二叉搜索树中查找第k大的元素。可以采用中序遍历的方式,将节点的值从小到大添加到数组中,然后返回数组中的倒数第k个元素即为答案。时间复杂度为O(N),空间复杂度为O(N)。也可以利用二叉搜索树的性质,从根节点开始遍历,每个节点记录其右子树的大小,根据大小可以找到第K大的元素。时间复杂度为O(log N),空间复杂度为O(1)。 ### 回答2: BST 是二叉搜索树,它是一种有序的二叉树,其中每个节点都存储一个键值,且左子树的值小于等于当前节点的值,右子树的值大于等于当前节点的值。因此,如果我们要找到 BST 中的第 k 大元素,我们可以利用 BST 的这种有序性质来帮助我们寻找。 一种有效的解决办法是使用中序遍历算法,在遍历的过程中维护一个计数器 count,记录当前已经遍历的节点数,如果 count 等于 k,直接返回当前节点的值即可。因为中序遍历算法遍历的顺序是左--右,所以返回的节点值就是第 k 大元素。 以下是实现该算法的例子,我们假设 BST 中不存在相同的值。 ``` class TreeNode: def __init__(self, val=None, left=None, right=None): self.val = val self.left = left self.right = right class Solution: def kthLargest(self, root: TreeNode, k: int) -> int: # 栈用于模拟中序遍历 stack = [] count = 0 # 记录当前已经遍历过的节点数 node = root while node or stack: while node: stack.append(node) node = node.right node = stack.pop() count += 1 if count == k: return node.val node = node.left ``` 该算法时间复杂度为 O(H+k),其中 H 为树的高度,k 为要查找的元素的下标。由于 BST 的性质,树的高度 H 最多为树中节点数 N(最坏情况下,BST 变成了一个链表),因此时间复杂度为 O(N+k)。 ### 回答3: 题目描述: 给定一棵二叉搜索树(BST)和一个整数k,找到其中第k大的元素。 解题思路: 首先,我们可以利用BST的性质,即左子树所有节点的值小于根节点的值,根节点的值小于右子树所有节点的值,来确定BST中某个节点的排名。 具体地,我们可以首先通过BST的中序遍历得到一个按照升序排列的节点值列表,然后按照降序遍历该列表并记录已经遍历的节点个数,当遍历到第k个节点时,就得到了所求的第k大节点的值。 但是,这种方法需要遍历整棵BST,时间复杂度为O(n),其中n是BST中节点的个数。而这题我们要求的是第k大节点,因此我们可以不必遍历整棵BST,可以在遍历BST时维护一个计数变量和一个全局变量,分别记录已经遍历的节点个数和第k大节点的值。 具体地,我们可以利用BST中序遍历得到一个按照升序排列的节点值列表。在遍历列表时,我们从最大的值开始,每次访问一个值,计数器就加1,当计数器达到k时,就求出了第k大节点的值。 代码实现: class Solution: def kthLargest(self, root: TreeNode, k: int) -> int: def inorder(node): if not node: return [] return inorder(node.left) + [node.val] + inorder(node.right) nums = inorder(root) return nums[-k]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值