classSolution: deftrap(self, height: List[int]) -> int: st=[] ans=0 for k,v inenumerate(height): while st and height[st[-1]]<v: pre=st.pop() if st: l,r=st[-1],k ans+=(r-l-1)*(min(height[l],height[r])-height[pre]) st.append(k) return ans
84 柱状图中最大的矩形
同款思路 不断拓展
1 2 3 4 5 6 7 8 9 10 11 12 13
classSolution: deflargestRectangleArea(self, heights: List[int]) -> int: st=[-1] heights.append(0) ans=0 for k,v inenumerate(heights): # 需要保证右边是最大的 while st and heights[st[-1]]>v: pre=st.pop() dis=k-st[-1]-1 ans=max(ans,dis*heights[pre]) st.append(k) return ans
classSolution: defmaximalRectangle(self, matrix: List[List[str]]) -> int: # 理解了 类似于 84 n=len(matrix[0]) height=[0]*(n+1) ans=0 for r in matrix: for i,c inenumerate(r): # 只包含 1 的最大矩形,并返回其面积 height[i]=0if c=='0'else height[i]+1 ans=max(ans,self.largestRectangleArea(height)) return ans deflargestRectangleArea(self, heights: List[int]) -> int: st=[-1] ans=0 for k,v inenumerate(heights): # 需要保证右边是最大的 while st and heights[st[-1]]>v: pre=st.pop() dis=k-st[-1]-1 ans=max(ans,dis*heights[pre]) st.append(k) return ans
316 去除重复字母
注意唯一 和 字典序
1 2 3 4 5 6 7 8 9 10 11 12 13 14
classSolution: defremoveDuplicateLetters(self, s: str) -> str: map = Counter(s) st = [] for i in s: # 保证唯一 if i in st: map[i]-=1 continue while st and st[-1]>i andmap[st[-1]]: st.pop() map[i]-=1 st.append(i) return''.join(st)
classSolution: defmaxNumber(self, nums1: List[int], nums2: List[int], k: int) -> List[int]: # 有所想法 立马想到归并 # 还是无从下手 defget_big_nums(nums,k): st=[] cnt=len(nums)-k for i in nums: while cnt and st and st[-1]<i: cnt-=1 st.pop() st.append(i) return st[:k] defmerge_nums(a,b): ans=[] while a or b: big=a if a>b else b ans.append(big.pop(0)) return ans returnmax(merge_nums(get_big_nums(nums1,i),get_big_nums(nums2,k-i)) for i inrange(k+1) if i<=len(nums1) and k-i<=len(nums2))
402 移掉k位数字
移除问题 对于位数移除之后单独考虑
1 2 3 4 5 6 7 8 9 10 11
classSolution: defremoveKdigits(self, num: str, k: int) -> str: st=[] for i in num: while k and st and st[-1]>i: k-=1 st.pop() st.append(i) # 对于位数移除之后单独考虑 st=st[:-k] if k else st return''.join(st).lstrip('0') or'0'
456 132模式
本题有所参考 确实学到 处理一条之后然后完善剩余的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
classSolution: deffind132pattern(self, nums: List[int]) -> bool: # 先进行一遍遍历 存左边最小的 # 从后操作即可 n=len(nums) min_vals=[nums[0]]*n for i inrange(1,n): min_vals[i]=min(min_vals[i-1],nums[i]) st=[] for i inrange(n-1,-1,-1): nxt_val=-inf while st and st[-1]<nums[i]: nxt_val=st.pop() if nxt_val>min_vals[i]: returnTrue st.append(nums[i]) returnFalse
496 下一个更大元素I
下一个最大/小问题
1 2 3 4 5 6 7 8 9 10 11 12 13
classSolution: defnextGreaterElement(self, nums1: List[int], nums2: List[int]) -> List[int]: st=[] map={} for k,v inenumerate(nums2): while st and nums2[st[-1]]<v: idx=st.pop() map[nums2[idx]]=v st.append(k) if st:map[v]=-1 print(map) return [map[i] for i in nums1]
503 下一个更大元素 II
上一题稍微优化即可 也可以对于范围进行优化 0~2n-2即可
1 2 3 4 5 6 7 8 9 10 11
classSolution: defnextGreaterElements(self, nums: List[int]) -> List[int]: st=[] n=len(nums) ans=[-1]*n for i inrange(2*n-1): #0~2n-1 是不行的 我们需要执行到 0~2*n-2 while st and nums[st[-1]%n]<nums[i%n]: idx=st.pop() ans[idx%n]=nums[i%n] st.append(i%n) return ans
581 最短无序连续子数组
困了 直接暴力
1 2 3 4 5 6 7 8 9 10 11
classSolution: deffindUnsortedSubarray(self, nums: List[int]) -> int: ans=sorted(nums) if ans==nums:return0 pre=0 n=len(nums) while pre<n and ans[pre]==nums[pre]:pre+=1 nxt=n-1 while nxt>=0and ans[nxt]==nums[nxt]:nxt-=1