Every day a Leetcode
题目来源:2336. 无限集中的最小数字
解法1:集合
由于一开始类中包含所有正整数,并且操作要么添加任意的正整数,要么删除最小的正整数,因此我们可以期望,在任意时刻,存在一个正整数 min_num,使得所有大于等于 min_num 都在类中。
我们可以使用一个有序集合 s 维护所有小于 min_num 的正整数,对于题目描述中的两种操作:
popSmallest()
:如果要删除最小的正整数,那么当集合 s 不为空时,我们删除 s 中最小的正整数(也是 s 最开头的数字),否则删除 min_num,并让 min_num 自增 1。addBack(int num)
:如果要添加一个正整数 num,如果它大于等于 min_num,则不进行任何操作,否则将其加入集合 s 中。
代码:
/** @lc app=leetcode.cn id=2336 lang=cpp** [2336] 无限集中的最小数字*/// @lc code=start
class SmallestInfiniteSet
{
private:set<int> s;int min_num = 1;public:SmallestInfiniteSet(){}int popSmallest(){if (s.empty())return min_num++;int x = *s.begin();s.erase(s.begin());return x;}void addBack(int num){if (num < min_num)s.insert(num);}
};/*** Your SmallestInfiniteSet object will be instantiated and called as such:* SmallestInfiniteSet* obj = new SmallestInfiniteSet();* int param_1 = obj->popSmallest();* obj->addBack(num);*/
// @lc code=end
结果:
复杂度分析:
时间复杂度:初始化需要的时间为 O(1),单次任意操作的时间复杂度为 O(logn),其中 n 是集合 s 中的元素个数,它不会超过已经操作的次数。
空间复杂度:O(n),即为有序集合 s 需要使用的空间。