You are given two arrays (without duplicates) nums1 and nums2 where nums1’s elements are subset of nums2. Find all the next greater numbers for nums1's elements in the corresponding places of nums2.
For example Input: nums1 = [4,1,2], nums2 = [1,3,4,2]. Output: [-1,3,-1]
用hashmap紀錄next greater number position
Greedy, main a decreasing stack, 持續更新越靠右的index
Use a stack to store the nums2[i] if it less than previous nubmers
Otherwise, store the number to a map to query
defnextGreaterElement(self,nums1: List[int],nums2: List[int]) -> List[int]: record ={} stack = []for n in nums2:while stack and stack[-1]< n: record[stack.pop()]= n stack.append(n)while stack: record[stack.pop()]=-1 res = []for n in nums1: res.append(record[n])return res
503. Next Greater Element II
Given a circular array, print the Next Greater Number for every element. The Next Greater Number of a number x is the first greater number to its traversing-order next in the array
Input: [1,2,1]Output: [2,-1,2]
"""2 pass, both from back of arrayfirst pass先拿到array increasing stack2nd pass 紀錄答案"""classSolution:defnextGreaterElements(self,nums: List[int]) -> List[int]: stack = []# frist passfor n in nums[::-1]:while stack and stack[-1]<= n: stack.pop() stack.append(n)# second pass res = []for n in nums[::-1]:while stack and stack[-1]<= n: stack.pop()if stack: res.append(stack[-1])else: res.append(-1) stack.append(n)return res[::-1]
739. Daily Temperatures
Given a list of daily temperatures T, return a list such that, for each day in the input, tells you how many days you would have to wait until a warmer temperature
For example T = [73, 74, 75, 71, 69, 72, 76, 73], your output should be [1, 1, 4, 2, 1, 1, 0, 0]
Use a stack
"""Traverse from back, stack store index and num in increasing orderWhile loop compare the cur num and stack[-1] num, pop the smaller num than itself"""defdailyTemperatures(self,T: List[int]) -> List[int]: n =len(T) stack = [] res = []for i inrange(n-1, -1, -1):while stack and T[stack[-1]]<= T[i]: stack.pop()if stack: res.append(stack[-1] - i)else: res.append(0) stack.append(i)return res[::-1]
239 Sliding Window Max
Given an array nums, there is a sliding window of size k which is moving from the very left of the array to the very right. You can only see the k numbers in the window. Each time the sliding window moves right by one position. Return the max sliding window.
Input: nums = [1,3,-1,-3,5,3,6,7], and k =3Output: [3,3,5,5,6,7]
Maintain a Dequeue in decreasing
defmaxSlidingWindow(self,nums: List[int],k:int) -> List[int]:ifnot k ornot nums:return []if k ==1:return nums# Maintain a decreasing queue which only k range from current idx# q[0] is the current maxdefhelper(q,idx): # if current max is from previous k if q and idx>=k and q[0]== nums[idx-k]: q.pop(0)# evict numbers on idx smaller than current idxwhile q and nums[idx]> q[-1]: q.pop() q.append(nums[idx]) q = []for i inrange(k):helper(q, i) ans = [q[0]]for i inrange(k,len(nums)):helper(q, i) ans.append(q[0])return ans
480. Sliding Window Median
Median is the middle value in an ordered integer list. If the size of the list is even, there is no middle value. So the median is the mean of the two middle value.
"""Maintain a sorted array"""defmedianSlidingWindow(self,nums: List[int],k:int) -> List[float]: ans = [] arr= []defhelper(idx,arr):if idx >= k: delete_idx = bisect.bisect_left(arr, nums[idx-k]) arr.pop(delete_idx) insert_idx = bisect.bisect(arr, nums[idx]) arr.insert(insert_idx, nums[idx])defgetMedium(arr): n =len(arr)if n%2:return arr[n//2]else:return (arr[n//2-1]+ arr[n//2])/2for i inrange(k):helper(i, arr) ans.append(getMedium(arr))for i inrange(k, len(nums)):helper(i, arr) ans.append(getMedium(arr))return ans
862. Shortest Subarray with Sum at Least K
Return the length of the shortest, non-empty, contiguous subarray of A with sum at least K.
If there is no non-empty subarray with sum at least K, return -1.
這題跟209的差異是num可能為負數
用一個dequeue紀錄 sum and index, dequeue in increasing order by sum
Update if we can find total - sum >= k, and kind updating to shorten the distant
defshortestSubarray(self,A: List[int],K:int) ->int: q = [[-1,0]] # [index, total] total =0 ans =float('inf')for i, n inenumerate(A): total += n while q and total - q[0][1] >= K: ans =min(ans, i - q[0][0]) q.pop(0)while q and total <= q[-1][1]: q.pop() q.append([i, total])return ans if ans !=float('inf')else-1
402. Remove K Digits
Given a non-negative integer num represented as a string, remove k digits from the number so that the new number is the smallest possible.
Input: num ="1432219", k =3Output:"1219"Input: num ="10", k =2Output:"0"
'''greedy + stackRemove the nums before cur num which are greater then cur num'''defremoveKdigits(self,num:str,k:int) ->str: stack = []for n in num:while k >0and stack and stack[-1]> n: stack.pop() k -=1 stack.append(n)if k: stack = stack[:-k]# if '0' in head # if ans is emptyreturn''.join(stack).lstrip('0')or'0'