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;;
        }
    }
};
相关推荐
2401_891482172 小时前
多平台UI框架C++开发
开发语言·c++·算法
无敌昊哥战神3 小时前
【LeetCode 257】二叉树的所有路径(回溯法/深度优先遍历)- Python/C/C++详细题解
c语言·c++·python·leetcode·深度优先
x_xbx3 小时前
LeetCode:148. 排序链表
算法·leetcode·链表
Darkwanderor3 小时前
三分算法的简单应用
c++·算法·三分法·三分算法
2401_831920744 小时前
分布式系统安全通信
开发语言·c++·算法
2401_877274244 小时前
从匿名管道到 Master-Slave 进程池:Linux 进程间通信深度实践
linux·服务器·c++
汉克老师4 小时前
GESP5级C++考试语法知识(八、链表(三)循环链表)
c++·约瑟夫问题·循环链表·gesp5级·gesp五级
阿贵---5 小时前
C++中的RAII技术深入
开发语言·c++·算法
PiKaMouse.5 小时前
navigation2-humble从零带读笔记第一篇:nav2_core
c++·算法·机器人
木井巳5 小时前
【递归算法】子集
java·算法·leetcode·决策树·深度优先