Skip to content

Commit 6c1ea54

Browse files
committed
Add Stack solutions
* Valid Parenthesis Expression * Evaluate Expression * Implement a Queue Using Stacks * Maximum of Sliding Window * Next Largest Number to the Right * Repeated Removal of Adjacent Duplicates
1 parent 77cb109 commit 6c1ea54

6 files changed

+177
-0
lines changed

kotlin/Stacks/EvaluateExpression.kt

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import java.util.Stack
2+
3+
fun evaluateExpression(s: String): Int {
4+
val stack = Stack<Int>()
5+
var currNum = 0
6+
var sign = 1
7+
var res = 0
8+
for (c in s) {
9+
if (c.isDigit()) {
10+
currNum = currNum * 10 + c.digitToInt()
11+
// If the current character is an operator, add 'curr_num' to
12+
// the result after multiplying it by its sign.
13+
} else if (c == '+' || c == '-') {
14+
res += currNum * sign
15+
// Update the sign and reset 'curr_num'.
16+
sign = if (c == '-') -1 else 1
17+
currNum = 0
18+
// If the current character is an opening parenthesis, a new
19+
// nested expression is starting.
20+
} else if (c == '(') {
21+
// Save the current 'res' and 'sign' values by pushing them
22+
// onto the stack, then reset their values to start
23+
// calculating the new nested expression.
24+
stack.push(res)
25+
stack.push(sign)
26+
res = 0
27+
sign = 1
28+
// If the current character is a closing parenthesis, a nested
29+
// expression has ended.
30+
} else if (c == ')') {
31+
// Finalize the result of the current nested expression.
32+
res += sign * currNum
33+
// Apply the sign of the current nested expression's result
34+
// before adding this result to the result of the outer
35+
// expression.
36+
res *= stack.pop()
37+
res += stack.pop()
38+
currNum = 0
39+
}
40+
}
41+
// Finalize the result of the overall expression.
42+
return res + currNum * sign
43+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import java.util.Stack
2+
3+
class Queue {
4+
5+
private val enqueueStack = Stack<Int>()
6+
private val dequeueStack = Stack<Int>()
7+
8+
fun enqueue(x: Int) {
9+
enqueueStack.push(x)
10+
}
11+
12+
private fun transferEnqueueToDequeue() {
13+
// If the dequeue stack is empty, push all elements from the enqueue stack
14+
// onto the dequeue stack. This ensures the top of the dequeue stack
15+
// contains the most recent value.
16+
if (dequeueStack.isEmpty()) {
17+
while (enqueueStack.isNotEmpty()) {
18+
dequeueStack.push(enqueueStack.pop())
19+
}
20+
}
21+
}
22+
23+
fun dequeue(): Int {
24+
transferEnqueueToDequeue()
25+
// Pop and return the value at the top of the dequeue stack.
26+
return if (dequeueStack.isNotEmpty()) {
27+
dequeueStack.pop()
28+
} else {
29+
-1
30+
}
31+
}
32+
33+
fun peek(): Int {
34+
transferEnqueueToDequeue()
35+
return if (dequeueStack.isNotEmpty()) {
36+
dequeueStack.peek()
37+
} else {
38+
-1
39+
}
40+
}
41+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
fun maximumsOfSlidingWindow(nums: List<Int>, k: Int): List<Int> {
2+
val res = mutableListOf<Int>()
3+
val dq = ArrayDeque<Pair<Int, Int>>()
4+
var left = 0
5+
var right = 0
6+
while (right < nums.size) {
7+
// 1) Ensure the values of the deque maintain a monotonic decreasing order
8+
// by removing candidates <= the current candidate.
9+
while (dq.isNotEmpty() && dq.last().first <= nums[right]) {
10+
dq.removeLast()
11+
}
12+
// 2) Add the current candidate.
13+
dq.add(Pair(nums[right], right))
14+
// If the window is of length 'k', record the maximum of the window.
15+
if (right - left + 1 == k) {
16+
// 3) Remove values whose indexes occur outside the window.
17+
while (dq.isNotEmpty() && dq.first().second < left) {
18+
dq.removeFirst()
19+
}
20+
// The maximum value of this window is the leftmost value in the
21+
// deque.
22+
res.add(dq.first().first)
23+
// Slide the window by advancing both 'left' and 'right'. The right
24+
// pointer always gets advanced so we just need to advance 'left'.
25+
left++
26+
}
27+
right++
28+
}
29+
return res
30+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import java.util.Stack
2+
3+
fun nextLargestNumberToTheRight(nums: List<Int>): List<Int> {
4+
val res = MutableList(nums.size) { 0 }
5+
val stack = Stack<Int>()
6+
// Find the next largest number of each element, starting with the
7+
// rightmost element.
8+
for (i in nums.size - 1 downTo 0) {
9+
// Pop values from the top of the stack until the current
10+
// value's next largest number is at the top.
11+
while (stack.isNotEmpty() && stack.peek() <= nums[i]) {
12+
stack.pop()
13+
}
14+
// Record the current value's next largest number, which is at
15+
// the top of the stack. If the stack is empty, record -1.
16+
res[i] = if (stack.isNotEmpty()) stack.peek() else -1
17+
stack.push(nums[i])
18+
}
19+
return res
20+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import java.util.Stack
2+
3+
fun repeatedRemovalOfAdjacentDuplicates(s: String): String {
4+
val stack = Stack<Char>()
5+
for (c in s) {
6+
// If the current character is the same as the top character on the stack,
7+
// a pair of adjacent duplicates has been formed. So, pop the top character
8+
// from the stack.
9+
if (stack.isNotEmpty() && c == stack.peek()) {
10+
stack.pop()
11+
}
12+
// Otherwise, push the current character onto the stack.
13+
else {
14+
stack.push(c)
15+
}
16+
}
17+
// Return the remaining characters as a string.
18+
return stack.joinToString("")
19+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import java.util.Stack
2+
3+
fun validParenthesisExpression(s: String): Boolean {
4+
val parenthesesMap = mapOf('(' to ')', '{' to '}', '[' to ']')
5+
val stack = Stack<Char>()
6+
for (c in s) {
7+
// If the current character is an opening parenthesis, push it
8+
// onto the stack.
9+
if (parenthesesMap.containsKey(c)) {
10+
stack.push(c)
11+
} else {
12+
// If the current character is a closing parenthesis, check if
13+
// it closes the opening parenthesis at the top of the stack.
14+
if (stack.isNotEmpty() && parenthesesMap[stack.peek()] == c) {
15+
stack.pop()
16+
} else {
17+
return false
18+
}
19+
}
20+
}
21+
// If the stack is empty, all opening parentheses were successfully
22+
// closed.
23+
return stack.isEmpty()
24+
}

0 commit comments

Comments
 (0)