Smallest Number in Infinite Set
Leetcode Daily Challenge (25th April, 2023)
Problem Statement:-
You have a set which contains all positive integers [1, 2, 3, 4, 5, ...]
.
Implement the SmallestInfiniteSet
class:
SmallestInfiniteSet()
Initializes the SmallestInfiniteSet object to contain all positive integers.int popSmallest()
Removes and returns the smallest integer contained in the infinite set.void addBack(int num)
Adds a positive integernum
back into the infinite set, if it is not already in the infinite set.
Link: https://leetcode.com/problems/smallest-number-in-infinite-set/description/
Problem Explanation with examples:-
Example 1
Input
["SmallestInfiniteSet", "addBack", "popSmallest", "popSmallest", "popSmallest", "addBack", "popSmallest", "popSmallest", "popSmallest"]
[[], [2], [], [], [], [1], [], [], []]
Output
[null, null, 1, 2, 3, null, 1, 4, 5]
Explanation
SmallestInfiniteSet smallestInfiniteSet = new SmallestInfiniteSet();
smallestInfiniteSet.addBack(2); // 2 is already in the set, so no change is made.
smallestInfiniteSet.popSmallest(); // return 1, since 1 is the smallest number, and remove it from the set.
smallestInfiniteSet.popSmallest(); // return 2, and remove it from the set.
smallestInfiniteSet.popSmallest(); // return 3, and remove it from the set.
smallestInfiniteSet.addBack(1); // 1 is added back to the set.
smallestInfiniteSet.popSmallest(); // return 1, since 1 was added back to the set and
// is the smallest number, and remove it from the set.
smallestInfiniteSet.popSmallest(); // return 4, and remove it from the set.
smallestInfiniteSet.popSmallest(); // return 5, and remove it from the set.
Constraints
1 <= num <= 1000
At most
1000
calls will be made in total topopSmallest
andaddBack
.
Intuition:-
We will use a dictionary to keep track of the numbers that have been popped.
Another variable will keep track of the smallest number that has not been popped.
When we pop the smallest number, we will add it to the dictionary and increment the smallest number that has not been popped.
When we add a number back, we will remove it from the dictionary and update the smallest number that has not been popped if the number is smaller than the smallest number that has not been popped.
Solution:-
Create a dictionary and a variable to keep track of the smallest number that has not been popped.
When we pop the smallest number, we will add it to the dictionary and increment the smallest number till we find a number that has not been popped using a while loop.
When we add a number back, we will remove it from the dictionary and update the smallest number that has not been popped if the number is smaller than the smallest number that has not been popped.
Code:-
JAVA Solution
import java.util.HashMap;
class SmallestInfiniteSet {
private HashMap<Integer, Integer> mp;
private int sm;
public SmallestInfiniteSet() {
mp = new HashMap<>();
sm = 1;
}
public int popSmallest() {
mp.put(sm, 1);
int x = sm;
while (mp.getOrDefault(sm, 0) != 0) {
sm++;
}
return x;
}
public void addBack(int num) {
if (mp.getOrDefault(num, 0) != 0) {
mp.put(num, 0);
if (sm > num) {
sm = num;
}
}
}
}
Python Solution
class SmallestInfiniteSet:
def __init__(self):
self.mp = {}
self.sm = 1
def popSmallest(self) -> int:
self.mp[self.sm] = 1
x = self.sm
while self.mp.get(self.sm,0) != 0:
self.sm += 1
return x
def addBack(self, num: int) -> None:
if self.mp.get(num,0) != 0:
self.mp[num] = 0
if self.sm > num:
self.sm = num
Complexity Analysis:-
TIME:-
The time complexity of the code is O(1) for both popSmallest and addBack as we are just doing constant time operations.
SPACE:-
The space complexity of the code is O(n) where n is the number of elements that have been popped as we are using a dictionary to keep track of the popped elements.