Skip to content

Commit 03d0b45

Browse files
authored
Merge pull request #31 from yeoshuheng/main
Monotonic Queue
2 parents 7afe680 + ac99759 commit 03d0b45

File tree

2 files changed

+65
-29
lines changed

2 files changed

+65
-29
lines changed

src/dataStructures/queue/MonotonicQueue.java

Lines changed: 8 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import java.util.ArrayDeque;
55

66
/**
7-
* Implementation of a non-increasing monotonic queue for certain (but common) use case:
7+
* Implementation of a non-increasing (decreasing) monotonic queue for certain (but common) use case:
88
* When larger objects pushed to the queue are able to replace and represent smaller objects that come before it.
99
* Callable methods are:
1010
* isEmpty()
@@ -20,8 +20,9 @@
2020
* 4 2 [1, 2] #2->1 [5, 3, 2] 2 kick out 1 #2->3
2121
* 5 4 [1, 2, 4] #4->2 [5,4] 4 kick out 2, 3 #4->2
2222
*/
23+
2324
public class MonotonicQueue<T extends Comparable<T>> {
24-
private Deque<Pair<T>> dq = new ArrayDeque<>(); // or LinkedList
25+
private Deque<T> dq = new ArrayDeque<>(); // or LinkedList
2526

2627
/**
2728
* Checks if queue is empty.
@@ -37,12 +38,10 @@ public boolean isEmpty() {
3738
*/
3839
public void push(T obj) {
3940
Integer count = 0;
40-
while (!dq.isEmpty() && obj.compareTo(dq.peekLast().value) >= 0) {
41-
Pair<T> popped = dq.pollLast();
42-
// accumulate count of objects that were popped to maintain the non-increasing property
43-
count += 1 + popped.countDeleted;
41+
while (!dq.isEmpty() && obj.compareTo(dq.peekLast()) > 0) {
42+
dq.pollLast(); // Removes elements that do not conform the non-increasing sequence.
4443
}
45-
dq.offerLast(new Pair<T>(obj, count));
44+
dq.offerLast(obj);
4645
}
4746

4847
/**
@@ -53,7 +52,7 @@ public T max() {
5352
if (isEmpty()) {
5453
return null;
5554
}
56-
return dq.peek().value;
55+
return dq.peek();
5756
}
5857

5958
/**
@@ -64,26 +63,6 @@ public T pop() {
6463
if (dq.isEmpty()) {
6564
return null;
6665
}
67-
Pair<T> node = dq.peek();
68-
if (node.countDeleted > 0) {
69-
node.countDeleted -= 1;
70-
return node.value;
71-
}
72-
dq.poll();
73-
return node.value;
74-
}
75-
76-
/**
77-
* Node class that is represented as a pair.
78-
* Tracks the deleted count and the value to be wrapped.
79-
*/
80-
private static class Pair<T> {
81-
private T value;
82-
private Integer countDeleted;
83-
84-
private Pair(T val, Integer count) {
85-
this.value = val;
86-
this.countDeleted = count;
87-
}
66+
return dq.poll(); // Returns & remove head of deque
8867
}
8968
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package test.dataStructures.queue;
2+
3+
import org.junit.Assert;
4+
import org.junit.Test;
5+
import src.dataStructures.queue.MonotonicQueue;
6+
public class MonotonicQueueTest {
7+
@Test
8+
public void testEmpty() {
9+
MonotonicQueue<Integer> q = new MonotonicQueue<>();
10+
Assert.assertEquals(true, q.isEmpty());
11+
Assert.assertEquals(null, q.max());
12+
Assert.assertEquals(null, q.pop());
13+
}
14+
15+
@Test
16+
public void testMax() {
17+
MonotonicQueue<Integer> q = new MonotonicQueue<>();
18+
q.push(2);
19+
Assert.assertEquals("2", q.max().toString());
20+
q.push(7);
21+
Assert.assertEquals("7", q.max().toString());
22+
q.push(1);
23+
Assert.assertEquals("7", q.max().toString());
24+
q.push(7);
25+
Assert.assertEquals("7", q.max().toString());
26+
q.push(5);
27+
Assert.assertEquals("7", q.max().toString());
28+
q.push(4);
29+
Assert.assertEquals("7", q.max().toString());
30+
q.push(3);
31+
q.push(2);
32+
q.push(5);
33+
Assert.assertEquals("7", q.max().toString());
34+
}
35+
36+
@Test
37+
public void testPop() {
38+
MonotonicQueue<Integer> q = new MonotonicQueue<>();
39+
q.push(2);
40+
q.push(7);
41+
q.push(1);
42+
q.push(7);
43+
q.push(5);
44+
q.push(4);
45+
q.push(3);
46+
q.push(2);
47+
q.push(5);
48+
q.push(2);
49+
50+
Assert.assertEquals("7", q.pop().toString());
51+
Assert.assertEquals("7", q.pop().toString());
52+
Assert.assertEquals("5", q.pop().toString());
53+
q.pop();
54+
Assert.assertEquals("2", q.pop().toString());
55+
Assert.assertEquals(null, q.pop());
56+
}
57+
}

0 commit comments

Comments
 (0)