Skip to content

Commit 4245f6f

Browse files
committed
WIP
1 parent 8ed8902 commit 4245f6f

File tree

7 files changed

+200
-0
lines changed

7 files changed

+200
-0
lines changed

.vscode/launch.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,13 @@
44
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
55
"version": "0.2.0",
66
"configurations": [
7+
{
8+
"type": "java",
9+
"name": "CodeLens (Launch) - Solution",
10+
"request": "launch",
11+
"mainClass": "EducativeIo.Courses.GrokkingTheCodingInterview.Ch13_TopKElements.PC3_FrequencyStack.Java.Solution",
12+
"projectName": "learning-computer-science"
13+
},
714
{
815
"type": "java",
916
"name": "Debug (Launch) Java",
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package EducativeIo.Courses.GrokkingTheCodingInterview.Ch13_TopKElements.PC3_FrequencyStack.Java;
2+
3+
class Element {
4+
int number;
5+
int frequency;
6+
int sequenceNumber;
7+
8+
public Element(int number, int frequency, int sequenceNumber) {
9+
this.number = number;
10+
this.frequency = frequency;
11+
this.sequenceNumber = sequenceNumber;
12+
}
13+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package EducativeIo.Courses.GrokkingTheCodingInterview.Ch13_TopKElements.PC3_FrequencyStack.Java;
2+
3+
import java.util.Comparator;
4+
5+
class ElementComparator implements Comparator<Element> {
6+
public int compare(Element e1, Element e2) {
7+
if (e1.frequency != e2.frequency) {
8+
return e2.frequency - e1.frequency;
9+
}
10+
// if both elements have same frequency, return the one that was pushed later
11+
return e2.sequenceNumber - e1.sequenceNumber;
12+
}
13+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package EducativeIo.Courses.GrokkingTheCodingInterview.Ch13_TopKElements.PC3_FrequencyStack.Java;
2+
3+
import java.util.HashMap;
4+
import java.util.Map;
5+
import java.util.PriorityQueue;
6+
7+
public class Solution {
8+
int sequenceNumber = 0;
9+
PriorityQueue<Element> maxHeap = new PriorityQueue<Element>(new ElementComparator());
10+
Map<Integer, Integer> frequencyMap = new HashMap<>();
11+
12+
public static void main(String[] args) {
13+
Solution frequencyStack = new Solution();
14+
frequencyStack.push(1);
15+
frequencyStack.push(2);
16+
frequencyStack.push(3);
17+
frequencyStack.push(2);
18+
frequencyStack.push(1);
19+
frequencyStack.push(2);
20+
frequencyStack.push(5);
21+
System.out.println(frequencyStack.pop());
22+
System.out.println(frequencyStack.pop());
23+
System.out.println(frequencyStack.pop());
24+
}
25+
26+
public void push(int num) {
27+
frequencyMap.put(num, frequencyMap.getOrDefault(num, 0) + 1);
28+
maxHeap.offer(new Element(num, frequencyMap.get(num), sequenceNumber++));
29+
}
30+
31+
public int pop() {
32+
int num = maxHeap.poll().number;
33+
34+
// decrement the frequency or remove if this is the last number
35+
if (frequencyMap.get(num) > 1) {
36+
frequencyMap.put(num, frequencyMap.get(num) - 1);
37+
} else {
38+
frequencyMap.remove(num);
39+
}
40+
41+
return num;
42+
}
43+
44+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package EducativeIo.Courses.GrokkingTheCodingInterview.Ch13_TopKElements.PC3_FrequencyStack.Java;
2+
3+
import static org.junit.jupiter.api.Assertions.*;
4+
5+
import java.time.Duration;
6+
import org.junit.jupiter.api.Test;
7+
import org.junit.jupiter.api.AfterEach;
8+
import org.junit.jupiter.api.BeforeEach;
9+
10+
public class SolutionTest {
11+
12+
Solution solution;
13+
14+
@BeforeEach
15+
public void setUp() throws Exception {
16+
solution = new Solution();
17+
}
18+
19+
@AfterEach
20+
public void tearDown() throws Exception {
21+
solution = null;
22+
}
23+
24+
@Test
25+
public void MainFunction() {
26+
assertTimeout(Duration.ofMillis(500), () -> {
27+
String[] args = new String[0];
28+
assertAll(() -> Solution.main(args));
29+
});
30+
}
31+
32+
@Test
33+
public void TrivialCase1() {
34+
// input = ;
35+
assertTimeout(Duration.ofMillis(500), () -> {
36+
// expected = ;
37+
// actual = Solution.;
38+
// assertEquals(expected, actual);
39+
});
40+
}
41+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
{
2+
"type": "Coding",
3+
"name": "Frequency Stack",
4+
"origin": {
5+
"name": "Educative",
6+
"link": "https://www.educative.io/courses/grokking-the-coding-interview/Y5zDWlVRz2p"
7+
},
8+
"companies": ["", ""],
9+
"categories": [{
10+
"name": "Courses",
11+
"children": [{
12+
"name": "Grokking the Coding Interview: Patterns for Coding Questions",
13+
"children": []
14+
}]
15+
},
16+
{
17+
"name": "Difficulty",
18+
"children": [{
19+
"name": "Hard",
20+
"children": []
21+
}]
22+
},
23+
{
24+
"name": "Pattern",
25+
"children": [{
26+
"name": "Top K Elements",
27+
"children": []
28+
}]
29+
}
30+
],
31+
"tags": ["Top K Elements"],
32+
"buckets": []
33+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# Problem Definition
2+
3+
## Description
4+
5+
Design a class that simulates a Stack data structure, implementing the following two operations:
6+
7+
1. `push(int num)`: Pushes the number ‘num’ on the stack.
8+
2. `pop()`: Returns the most frequent number in the stack. If there is a tie, return the number which was pushed later.
9+
10+
Example:
11+
12+
```plaintext
13+
After following push operations: push(1), push(2), push(3), push(2), push(1), push(2), push(5)
14+
15+
1. pop() should return 2, as it is the most frequent number
16+
2. Next pop() should return 1
17+
3. Next pop() should return 2
18+
```
19+
20+
## Discussion
21+
22+
### Approach
23+
24+
This problem follows the **Top ‘K’ Elements** pattern, and shares similarities with **Top ‘K’ Frequent Numbers**.
25+
26+
We can use a **Max Heap** to store the numbers. Instead of comparing the numbers we will compare their frequencies so that the root of the heap is always the most frequently occurring number. There are two issues that need to be resolved though:
27+
28+
1. How can we keep track of the frequencies of numbers in the heap? When we are pushing a new number to the **Max Heap**, we don’t know how many times the number has already appeared in the **Max Heap**. To resolve this, we will maintain a **HashMap** to store the current frequency of each number. Thus whenever we push a new number in the heap, we will increment its frequency in the HashMap and when we pop, we will decrement its frequency.
29+
2. If two numbers have the same frequency, we will need to return the number which was pushed later while popping. To resolve this, we need to attach a sequence number to every number to know which number came first.
30+
31+
In short, we will keep three things with every number that we push to the heap:
32+
33+
```plaintext
34+
1. number // value of the number
35+
2. frequency // current frequency of the number when it was pushed to the heap
36+
3. sequenceNumber // a sequence number, to know what number came first
37+
```
38+
39+
#### Time Complexity
40+
41+
The time complexity of `push()` and `pop()` is O(logN) where ‘N’ is the current number of elements in the heap.
42+
43+
#### Space Complexity
44+
45+
We will need O(N) space for the heap and the map, so the overall space complexity of the algorithm is O(N).
46+
47+
## Notes
48+
49+
## References

0 commit comments

Comments
 (0)