Skip to content

Commit 2bc977e

Browse files
committed
update
1 parent 59dbed6 commit 2bc977e

18 files changed

+1045
-538
lines changed

README.md

Lines changed: 519 additions & 519 deletions
Large diffs are not rendered by default.

[H]array/[H]array-sliding-window/209-minimum-size-subarray-sum.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ def minSubArrayLen(self, target: int, nums: List[int]) -> int:
1717
'''
1818
1. notice: only works for positive elements
1919
2. if num can be negative then use monotonic queue and prefix sum and sliding window
20+
3. think about [20, -30, 20, 10] and 30, correct res should be 2
2021
'''
2122

2223
class Solution:
@@ -48,6 +49,7 @@ def valid(length):
4849
'''
4950
1. notice: only works for positive elements
5051
2. if num can be negative then use monotonic queue and prefix sum and sliding window
52+
3. think about [-10, -10, -10, 20] and 20, correct res should be 1
5153
'''
5254

5355
class Solution:
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
from collections import deque
2+
class Solution:
3+
def longestSubarray(self, nums: List[int], limit: int) -> int:
4+
res = 0
5+
min_queue = deque([])
6+
max_queue = deque([])
7+
left = 0
8+
for right in range(len(nums)):
9+
while min_queue and nums[min_queue[- 1]] >= nums[right]:
10+
min_queue.pop()
11+
min_queue.append(right)
12+
while max_queue and nums[max_queue[- 1]] <= nums[right]:
13+
max_queue.pop()
14+
max_queue.append(right)
15+
while nums[max_queue[0]] - nums[min_queue[0]] > limit:
16+
left += 1
17+
if min_queue[0] < left:
18+
min_queue.popleft()
19+
if max_queue[0] < left:
20+
max_queue.popleft()
21+
res = max(res, right - left + 1)
22+
return res
23+
24+
# time O(n), each num will only pop and push twice and both cost O(1)
25+
# space O(n), due to deque's size
26+
# using stack and queue and montonic and monotonic queue and sliding window
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
class Solution:
2+
def maxResult(self, nums: List[int], k: int) -> int:
3+
dp = [float('-inf') for _ in range(len(nums))]
4+
dp[0] = nums[0]
5+
6+
for right in range(1, len(nums)):
7+
for left in range(max(0, right - k), right):
8+
dp[right] = max(dp[right], dp[left] + nums[right])
9+
return dp[- 1]
10+
11+
# time O(nk)
12+
# space O(n)
13+
# using dp (this will TLE)
14+
15+
from collections import deque
16+
class Solution:
17+
def maxResult(self, nums: List[int], k: int) -> int:
18+
dp = [float('-inf') for _ in range(len(nums))]
19+
dp[0] = nums[0]
20+
queue = deque([])
21+
22+
for right in range(len(nums)):
23+
left = right - k
24+
while queue and queue[0] < left:
25+
queue.popleft()
26+
if queue:
27+
dp[right] = dp[queue[0]] + nums[right]
28+
while queue and dp[queue[- 1]] <= dp[right]:
29+
queue.pop()
30+
queue.append(right)
31+
32+
return dp[- 1]
33+
34+
# time O(n)
35+
# space O(n)
36+
# using stack and queue and montonic and monotonic queue and sliding window and dp
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
from collections import deque
2+
class Solution:
3+
def maxSlidingWindow(self, nums: List[int], k: int) -> List[int]:
4+
res = []
5+
queue = deque([])
6+
for right, num in enumerate(nums):
7+
left = right - k + 1
8+
while queue and nums[queue[- 1]] <= num:
9+
queue.pop()
10+
queue.append(right)
11+
while queue and queue[0] < left:
12+
queue.popleft()
13+
if left >= 0:
14+
res.append(nums[queue[0]])
15+
return res
16+
17+
# time O(n)
18+
# space O(k)
19+
# using stack and queue and montonic and monotonic queue and sliding window
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
class Solution:
2+
def nextGreaterElement(self, nums1: List[int], nums2: List[int]) -> List[int]:
3+
4+
val_idx = {}
5+
for i, num in enumerate(nums1):
6+
val_idx[num] = i
7+
8+
res = [- 1 for _ in range(len(nums1))]
9+
stack = []
10+
for i in range(len(nums2)):
11+
while stack and nums2[stack[- 1]] < nums2[i]:
12+
idx = stack.pop()
13+
if nums2[idx] in val_idx:
14+
res[val_idx[nums2[idx]]] = nums2[i]
15+
stack.append(i)
16+
return res
17+
18+
# time O(n)
19+
# space O(n), due to stack and hashmap
20+
# using stack and queue and montonic and monotonic stack (consider one side’s relationship) and hashmap
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
class Solution:
2+
def dailyTemperatures(self, temperatures: List[int]) -> List[int]:
3+
res = [0 for _ in range(len(temperatures))]
4+
stack = []
5+
for i in range(len(temperatures)):
6+
while stack and temperatures[stack[- 1]] < temperatures[i]:
7+
idx = stack.pop()
8+
res[idx] = i - idx
9+
stack.append(i)
10+
return res
11+
12+
# time O(n), each temperature will only pop and push once and both cost O(1)
13+
# space O(n), due to stack's size
14+
# using stack and queue and montonic and monotonic stack (consider one side’s relationship)
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
from collections import deque
2+
class Solution:
3+
def shortestSubarray(self, nums: List[int], k: int) -> int:
4+
prefix = [0 for _ in range(len(nums) + 1)]
5+
total = 0
6+
for i, num in enumerate(nums):
7+
total += num
8+
prefix[i + 1] = total
9+
10+
res = float('inf')
11+
queue = deque([])
12+
for i in range(len(prefix)):
13+
while queue and prefix[i] - prefix[queue[0]] >= k:
14+
idx = queue.popleft()
15+
res = min(res, i - idx)
16+
while queue and prefix[queue[- 1]] >= prefix[i]:
17+
queue.pop()
18+
queue.append(i)
19+
return res if res != float('inf') else - 1
20+
21+
# time O(n)
22+
# space O(n)
23+
# using stack and queue and montonic and monotonic queue and sliding window and prefix
24+
'''
25+
1. monotonic queue store the potential subarray's head idices
26+
2. monotonic queue needs to store the smallest prefix sum at queue's head
27+
3. because smaller prefix gets more chance to fulfill the condition
28+
4. once it met condition, record it, then popleft it (cur round is the best condition for shortest)
29+
5. if cur idx's prefix sum is smaller than queue's tail, then pop from queue (using cur idx is shorter)
30+
6. append cur idx in queue
31+
'''
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
class Solution:
2+
def minRemoveToMakeValid(self, s: str) -> str:
3+
res = []
4+
balance = 0
5+
for c in s:
6+
if c == '(':
7+
balance += 1
8+
res.append(c)
9+
elif c == ')':
10+
if balance > 0:
11+
balance -= 1
12+
res.append(c)
13+
else:
14+
res.append(c)
15+
16+
balance = 0
17+
for i in range(len(res) - 1, - 1, - 1):
18+
if res[i] == ')':
19+
balance += 1
20+
elif res[i] == '(':
21+
if balance > 0:
22+
balance -= 1
23+
else:
24+
res[i] = ''
25+
else:
26+
continue
27+
28+
return ''.join(res)
29+
30+
# time O(n), due to traverse twice
31+
# space O(n)
32+
# using stack and queue and variables to simulate stack
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
class MinStack:
2+
3+
def __init__(self):
4+
self.stack = []
5+
self.min_num = None
6+
7+
def push(self, val: int) -> None:
8+
if self.min_num == None:
9+
self.stack.append(0)
10+
self.min_num = val
11+
elif val < self.min_num:
12+
self.stack.append(val - self.min_num)
13+
self.min_num = val
14+
else:
15+
self.stack.append(val - self.min_num)
16+
17+
def pop(self) -> None:
18+
diff = self.stack.pop()
19+
if len(self.stack) == 0:
20+
self.min_num = None
21+
elif diff < 0:
22+
self.min_num += abs(diff)
23+
24+
def top(self) -> int:
25+
diff = self.stack[- 1]
26+
if diff < 0:
27+
return self.min_num
28+
return self.min_num + diff
29+
30+
def getMin(self) -> int:
31+
return self.min_num
32+
33+
# Your MinStack object will be instantiated and called as such:
34+
# obj = MinStack()
35+
# obj.push(val)
36+
# obj.pop()
37+
# param_3 = obj.top()
38+
# param_4 = obj.getMin()
39+
40+
# time O(1)
41+
# space O(n)
42+
# using stack and queue and implement stack/queue and one stack
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
from collections import deque
2+
class MyStack:
3+
4+
def __init__(self):
5+
self.queue = deque([])
6+
7+
def push(self, x: int) -> None:
8+
old_element_count = len(self.queue)
9+
self.queue.append(x)
10+
for _ in range(old_element_count):
11+
self.queue.append(self.queue.popleft())
12+
13+
def pop(self) -> int:
14+
return self.queue.popleft()
15+
16+
def top(self) -> int:
17+
return self.queue[0]
18+
19+
def empty(self) -> bool:
20+
return len(self.queue) == 0
21+
22+
# Your MyStack object will be instantiated and called as such:
23+
# obj = MyStack()
24+
# obj.push(x)
25+
# param_2 = obj.pop()
26+
# param_3 = obj.top()
27+
# param_4 = obj.empty()
28+
29+
# time O(n), due to push, and others are O(1)
30+
# space O(n), due to queue
31+
# using stack and queue and implement stack/queue and one queue
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
class TextEditor:
2+
3+
def __init__(self):
4+
self.left = []
5+
self.right = []
6+
7+
def addText(self, text: str) -> None:
8+
for c in text:
9+
self.left.append(c)
10+
11+
def deleteText(self, k: int) -> int:
12+
res = 0
13+
while self.left and k:
14+
self.left.pop()
15+
k -= 1
16+
res += 1
17+
return res
18+
19+
def cursorLeft(self, k: int) -> str:
20+
while self.left and k:
21+
self.right.append(self.left.pop())
22+
k -= 1
23+
res = ''
24+
for i in range(len(self.left) - 1, - 1, - 1):
25+
res = self.left[i] + res
26+
if len(res) == 10:
27+
break
28+
return res
29+
30+
def cursorRight(self, k: int) -> str:
31+
while self.right and k:
32+
self.left.append(self.right.pop())
33+
k -= 1
34+
res = ''
35+
for i in range(len(self.left) - 1, - 1, - 1):
36+
res = self.left[i] + res
37+
if len(res) == 10:
38+
break
39+
return res
40+
41+
# Your TextEditor object will be instantiated and called as such:
42+
# obj = TextEditor()
43+
# obj.addText(text)
44+
# param_2 = obj.deleteText(k)
45+
# param_3 = obj.cursorLeft(k)
46+
# param_4 = obj.cursorRight(k)
47+
48+
# time O(s) for add, O(1) for init, others are O(k)
49+
# space O(n)
50+
# using stack and queue and stack to simulate and two stacks
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
class MyQueue:
2+
3+
def __init__(self):
4+
self.stack1 = []
5+
self.stack2 = []
6+
7+
def push(self, x: int) -> None:
8+
self.stack1.append(x)
9+
10+
def pop(self) -> int:
11+
self.peek()
12+
return self.stack2.pop()
13+
14+
def peek(self) -> int:
15+
if self.stack2:
16+
return self.stack2[- 1]
17+
while self.stack1:
18+
self.stack2.append(self.stack1.pop())
19+
return self.stack2[- 1]
20+
21+
def empty(self) -> bool:
22+
return len(self.stack1) == 0 and len(self.stack2) == 0
23+
24+
# Your MyQueue object will be instantiated and called as such:
25+
# obj = MyQueue()
26+
# obj.push(x)
27+
# param_2 = obj.pop()
28+
# param_3 = obj.peek()
29+
# param_4 = obj.empty()
30+
31+
# time O(1) for push(), empty() ,and initiation, amortized O(1) for pop(), peek()
32+
# space O(n), due to two stacks
33+
# using stack and queue and implement stack/queue and two stacks

0 commit comments

Comments
 (0)