LeetCode:2336. 无限集中的最小数字(hash模拟 C++)

目录

[2336. 无限集中的最小数字](#2336. 无限集中的最小数字)

题目描述:

实现代码与解析:

set

原理思路:

优先级队列


2336. 无限集中的最小数字

题目描述:

现有一个包含所有正整数的集合 [1, 2, 3, 4, 5, ...]

实现 SmallestInfiniteSet 类:

  • SmallestInfiniteSet() 初始化 SmallestInfiniteSet 对象以包含 所有 正整数。
  • int popSmallest() 移除 并返回该无限集中的最小整数。
  • void addBack(int num) 如果正整数 num 存在于无限集中,则将一个 num 添加 到该无限集中。

示例:

复制代码
输入
["SmallestInfiniteSet", "addBack", "popSmallest", "popSmallest", "popSmallest", "addBack", "popSmallest", "popSmallest", "popSmallest"]
[[], [2], [], [], [], [1], [], [], []]
输出
[null, null, 1, 2, 3, null, 1, 4, 5]

解释
SmallestInfiniteSet smallestInfiniteSet = new SmallestInfiniteSet();
smallestInfiniteSet.addBack(2);    // 2 已经在集合中,所以不做任何变更。
smallestInfiniteSet.popSmallest(); // 返回 1 ,因为 1 是最小的整数,并将其从集合中移除。
smallestInfiniteSet.popSmallest(); // 返回 2 ,并将其从集合中移除。
smallestInfiniteSet.popSmallest(); // 返回 3 ,并将其从集合中移除。
smallestInfiniteSet.addBack(1);    // 将 1 添加到该集合中。
smallestInfiniteSet.popSmallest(); // 返回 1 ,因为 1 在上一步中被添加到集合中,
                                   // 且 1 是最小的整数,并将其从集合中移除。
smallestInfiniteSet.popSmallest(); // 返回 4 ,并将其从集合中移除。
smallestInfiniteSet.popSmallest(); // 返回 5 ,并将其从集合中移除。

提示:

  • 1 <= num <= 1000
  • 最多调用 popSmallestaddBack 方法 共计 1000

实现代码与解析:

set

cpp 复制代码
class SmallestInfiniteSet {
public:
    set<int> s;
    int m = 1; // 记录最小值
    SmallestInfiniteSet() {

    }
    
    int popSmallest() {
        int res = 0;
        if (s.empty()) {
            res = m++;
        } else {
            res = *s.begin();
            s.erase(s.begin());
        }
        return res;
    }
    
    void addBack(int num) {
        if (num < m) {
            s.insert(num);
        }
    }
};
java 复制代码
class SmallestInfiniteSet {

    private TreeSet<Integer> set;
    private int m = 1;

    public SmallestInfiniteSet() {
        set = new TreeSet<Integer>();
    }
    
    public int popSmallest() {
        return set.isEmpty() ? m++ : set.pollFirst();
    }
    
    public void addBack(int num) {
        if (num < m) set.add(num);
    }
}

原理思路:

m 来表示在12345....序列中还没有pop出的最小值,set用来存放新add并且小于m的值,毕竟大于m的值已经存在且未pop出,在popSmallest函数中,若set为空,说明最小值为m,不为空,说明add的数有小于m的,返回set的第一个数。当然,很显然,这题用优先级队列也是可以写的。

不过要注意,优先级队列不能去重,添加的数可能已经存在与队列,所以要多一个数组来判断一下。

优先级队列

cpp 复制代码
class SmallestInfiniteSet {
public:
    priority_queue<int, vector<int>, greater<int>> q;
    int m = 1; // 记录最小值
    vector<bool> d = vector<bool> (1010, false);
    SmallestInfiniteSet() {

    }
    
    int popSmallest() {
        int res = 0;
        if (q.empty()) {
            res = m++;
        } else {
            res = q.top();
            q.pop();
            d[res] = false;
        }
        return res;
    }
    
    void addBack(int num) {
        if (num < m && !d[num]) {
            q.push(num);
            d[num] = true;;
        }
    }
};
相关推荐
好好学习O(∩_∩)O8 分钟前
11-23刷题记录
算法·leetcode·职场和发展
小林熬夜学编程25 分钟前
【Linux系统编程】第五十弹---构建高效单例模式线程池、详解线程安全与可重入性、解析死锁与避免策略,以及STL与智能指针的线程安全性探究
linux·运维·服务器·c语言·c++·安全·单例模式
凯子坚持 c1 小时前
C++之二叉搜索树:高效与美的极致平衡
开发语言·c++
埋头编程~1 小时前
【C++】踏上C++学习之旅(十):深入“类和对象“世界,掌握编程黄金法则(五)(最终篇,内含初始化列表、静态成员、友元以及内部类等等)
java·c++·学习
小小小汐-1 小时前
【leetcode】动态规划
leetcode·动态规划·哈希算法
亚图跨际1 小时前
MATLAB和C++及Python流式细胞术
c++·python·matlab·流式细胞术
海绵波波1071 小时前
C++11:多线程编程
c++
程序猿阿伟1 小时前
《进程隔离机制:C++多进程编程安全的坚固堡垒》
服务器·c++·安全
gkdpjj1 小时前
C++优选算法十四 优先级队列(堆)
开发语言·数据结构·c++·算法
几窗花鸢1 小时前
力扣面试经典 150(上)
数据结构·c++·算法·leetcode