格式:

题号+题名+简单思路+code

T1: 两数之和

  • 不考虑去重,只找出第一个解;使用哈希表记录出现过的数字,O(N)时间复杂度
func twoSum(nums []int, target int) []int {if len(nums)==0 {return nil}tmp:=make(map[int]int,len(nums))for i,v := range nums {if j,ok:=tmp[target-v];ok {return []int{j,i}}tmp[v]=i}return nil
}
  • 哈希法能找出无序数组中所有和为定值的组合;但不能去重

※T560:和为K的子数组

  • 利用哈希字典找出所有和为K的子数组
  • 类似两数之和(两数之差),先转化成前缀和;前缀和用于处理数组区间问题
  • sum[j]-k=sum[i]
func subarraySum(nums []int, k int) int {memo:=make([]int,len(nums)+1)for i:=1;i<len(memo);i++ {memo[i]=memo[i-1]+nums[i-1]}count:=0dict:=make(map[int]int,0)for i:=0;i<len(memo);i++ {    // 注意i从0开始if c,ok:=dict[memo[i]-k];ok {count+=c}dict[memo[i]]++}return count
}

剑指57:和为s的连续正数序列

  • 同样对于连续子数组和我们转化为前缀和数组
  • 可以使用哈希表,也可以因为前缀和是有序数组,使用滑动窗口
  • 哈希表
class Solution:def findContinuousSequence(self, target: int) -> List[List[int]]:if target<=2:return []tmp=[i for i in range((target+1)//2+1)]pre=0for i in range(len(tmp)):tmp[i]=pre+tmp[i]pre=tmp[i]memo=dict()ans=[]for i in range(len(tmp)):if tmp[i]-target in memo:ans.append([j for j in range(memo[tmp[i]-target]+1, i+1)])memo[tmp[i]]=ireturn ans
  • 滑动窗口
class Solution:def findContinuousSequence(self, target: int) -> List[List[int]]:if target<=2:return []tmp=[i for i in range((target+1)//2+1)]pre=0for i in range(len(tmp)):tmp[i]=pre+tmp[i]pre=tmp[i]i=0ans=[]for j in range(len(tmp)):if tmp[j]-tmp[i]<=target:passelse:while j>i and tmp[j]-tmp[i]>target:i+=1if tmp[j]-tmp[i]==target:ans.append([k for k in range(i+1,j+1)])return ans

T15:三数之和

  • 考虑去重,所有解;使用排序+双指针;最坏情况为O(N^2)时间复杂度
import "sort"
func threeSum(nums []int) [][]int {target:=0ans:=[][]int{}sort.Ints(nums)for i:=0;i<len(nums)-2;i++ {if nums[i]>target {break}if i>0 && nums[i]==nums[i-1] {continue}lo:=i+1hi:=len(nums)-1a:=nums[i]for lo<hi && lo>=i+1 && hi<=len(nums)-1 {b:=nums[lo]c:=nums[hi]if a+b+c > target {hi--} else if a+b+c < target {lo++} else {ans=append(ans,[]int{a,b,c})for lo<hi && nums[hi-1]==nums[hi]{hi--}for lo<hi && nums[lo+1]==nums[lo] {lo++}lo++hi--}}}return ans
}
  • python3
class Solution:def threeSum(self, nums: List[int]) -> List[List[int]]:nums=sorted(nums)ans=[]for i in range(len(nums)-2):if i>0 and nums[i]==nums[i-1]:continuex=nums[i]left=i+1right=len(nums)-1while left<right:if x+nums[left]+nums[right]>0:while left<right and nums[right-1]==nums[right]:right-=1right-=1elif x+nums[left]+nums[right]<0:while left<right and nums[left+1]==nums[left]:left+=1left+=1else:ans.append([x, nums[left], nums[right]])while left<right and nums[left+1]==nums[left]:left+=1left+=1while left<right and nums[right-1]==nums[right]:right-=1right-=1return ans

T11:盛最多的水的容器

  • 双指针+短板效应;O(N)时间复杂度
func maxArea(height []int) int {n:=len(height)lo:=0hi:=n-1maxA:=0maxH:=0for lo<hi {if height[lo]<height[hi] {tmp:=(hi-lo)*height[lo]if tmp> maxA {maxA=tmp}maxH=height[lo]for lo<hi && height[lo+1]<=maxH {lo++}lo++} else {tmp:=(hi-lo)*height[hi]if tmp>maxA {maxA=tmp}maxH=height[hi]for lo<hi && height[hi-1]<=maxH {hi--}hi--}}return maxA
}

T16:最接近的三数之和

  • 由于计算的是和,所以无需考虑重复性;排序+双指针;O(N^2)时间复杂度
import "math"
import "sort"
func threeSumClosest(nums []int, target int) int {sort.Ints(nums)tmp:=math.Inf(0)var ans intfor i:=0;i<len(nums)-2;i++ {if i>0 && nums[i]==nums[i-1] {continue}t:=nums[i]lo:=i+1hi:=len(nums)-1for lo<hi {currVal:=t+nums[lo]+nums[hi]-targetc:=math.Abs(float64(currVal))if c<tmp {tmp=cans=currVal+target}if currVal>0 {hi--} else if currVal<0 {lo++} else {return target}}}return ans
}

T739:每日温度

  • 单调栈(递减栈)
class Solution:def dailyTemperatures(self, T: List[int]) -> List[int]:T.append(float("inf"))stack=[]ans=[0 for i in range(len(T))]for idx in range(len(T)):while len(stack)>0 and T[stack[-1]]<T[idx]:tmp=stack.pop()ans[tmp]=0 if idx==len(T)-1 else idx-tmpstack.append(idx)return ans[:-1]
func dailyTemperatures(T []int) []int {stack:=[]int{}ans:=make([]int, len(T))for i:=0;i<len(T);i++ {for len(stack)>0 && T[stack[len(stack)-1]]<T[i] {ans[stack[len(stack)-1]]=i-stack[len(stack)-1]stack=stack[:len(stack)-1]}stack=append(stack, i)}for i:=0;i<len(stack);i++ {ans[stack[i]]=0}return ans
}

※T316:去除重复字母

  • 维持一个单增栈
  • 出栈时需要保证相同字母在后续也会出现,对于stack中记录的字母就略过
func removeDuplicateLetters(s string) string {position:=[26]int{}memo:=[26]bool{}for i:=0;i<len(s);i++ {position[s[i]-'a']=i}stack:=[]byte{}for i:=0;i<len(s);i++ {if memo[s[i]-'a'] {continue}for len(stack)>0 && stack[len(stack)-1]>s[i] && position[stack[len(stack)-1]-'a']>i {x:=stack[len(stack)-1]stack=stack[:len(stack)-1]memo[x-'a']=false}stack=append(stack, s[i])memo[s[i]-'a']=true}return string(stack)
}

T84:柱状图中的最大矩形

  • 单调栈;适用于解决如找到第一个比其大/小这样的遍历问题;将O(N^2)→O(N)
  • 如单边的数矮个问题/升温天数T739和双边的T84
  1. 保证最后一个元素出栈
  2. 更新最值
  3. 双边扩展需要在栈中加辅助数-1 / re-index
  • 使用倒数第二个索引来明确正确左边界
class Solution {public int largestRectangleArea(int[] heights) {int ans = 0;Stack<Integer> stack = new Stack<>();for (int i=0;i<heights.length;i++) {while (stack.size()>0 && heights[stack.peek()] > heights[i]) {int x = stack.peek();stack.pop();int s = stack.size()>0?stack.peek():-1;ans = Math.max(ans, heights[x]*(i-s-1));}stack.push(i);}while (stack.size()>0) {int x = stack.peek();stack.pop();int s = stack.size()>0?stack.peek():-1;ans = Math.max(ans, heights[x]*(heights.length-s-1));}return ans;}
}
  • re-index
type Stack []intfunc (s *Stack) Push(i int) {*s=append(*s,i)
}func (s *Stack) Pop() int {i:=(*s)[len(*s)-1]*s=(*s)[:len(*s)-1]return i
}func (s Stack) Peek() int {return s[len(s)-1]
}func largestRectangleArea(heights []int) int {flag:=-1maxVal:=0currIdx:=0heights=append(heights,flag)stack:=Stack{}for idx,val:=range heights {if len(stack)==0 || heights[stack.Peek()]<=val {stack.Push(idx)} else {for len(stack)>0 && heights[stack.Peek()]>val {currIdx=stack.Pop()tmp:=(idx-currIdx)*heights[currIdx]if tmp>maxVal {maxVal=tmp}}stack.Push(currIdx)heights[currIdx]=val}}return maxVal
}

T85:最大矩形

  • 将该题看作m个柱状图最大矩形问题求全局最值
  • 单调栈的第一种写法,使用栈中倒数第二个索引来计算左边界
class Solution {public int maximalRectangle(char[][] matrix) {if (matrix.length==0) return 0;int ans = 0;int[] heights = new int[matrix[0].length];for (int i=0;i<matrix.length;i++) {for (int j=0;j< heights.length;j++) {if (matrix[i][j]=='1') heights[j]++;else heights[j]=0;}Stack<Integer> stack = new Stack<>();for (int j=0;j<heights.length;j++) {while (stack.size()>0 && heights[stack.peek()]>heights[j]) {int idx2 = stack.pop();int idx1 = stack.size()>0?stack.peek():-1;ans = Math.max(ans, (j-idx1-1)* heights[idx2]);}stack.push(j);}for (int j=0;j<stack.size();j++) {int idx2 = stack.get(j);int idx1 = j>0?stack.get(j-1):-1;ans = Math.max(ans, (heights.length-idx1-1)*heights[idx2]);}}return ans;}
}

※T986:区间列表交集

  • 双指针;最小区间右端点;O(M+N)时间复杂度
  • 同样的逻辑不能改成左端点
  • 类似归并排序最后的归并操作
func intervalIntersection(A [][]int, B [][]int) [][]int {point1:=0point2:=0ans:=[][]int{}for point1<len(A) && point2<len(B) {list1:=A[point1]list2:=B[point2]left:=max(list1[0], list2[0])if list1[1]<list2[1] {if list1[1]>=list2[0] {ans=append(ans, []int{left, list1[1]})}point1++} else {if list1[0]<=list2[1] {ans=append(ans, []int{left, list2[1]})}point2++}}return ans
}func max(i int, j int) int {if i>j {return i} else {return j}
}

T56: 合并区间

  • 区间问题,先排序
  • 从相交区间中扩展min_startmax_end
import "sort"func merge(intervals [][]int) [][]int {if len(intervals)==0 {return nil}ans:=[][]int{}sort.Slice(intervals, func(i int, j int) bool {return intervals[i][0]<intervals[j][0]})min_start:=intervals[0][0]max_end:=intervals[0][1]for i:=1;i<len(intervals);i++ {if intervals[i][0]<=max_end {if max_end<intervals[i][1] {max_end=intervals[i][1]}} else {ans=append(ans,[]int{min_start,max_end})min_start=intervals[i][0]max_end=intervals[i][1]}}ans=append(ans,[]int{min_start,max_end})return ans
}

※T239:滑动窗口的最大值

  • 使用单调队列的结构,保持窗口内降序,这样取最大值为O(1)
  • 存放的是索引值,首先将不在窗口内的删除,再删除窗口内小于当前值的所有值,最后插入当前值,并输出窗口中第一个值作为当前最大值
  • 平均时间复杂度为O(N)
class Solution:def maxSlidingWindow(self, nums: List[int], k: int) -> List[int]:ans=[]window=[]for i,num in enumerate(nums):while len(window)>0 and nums[window[-1]]<num:window.pop()window.append(i)if i>=k-1:ans.append(nums[window[0]])if window[0]==i-k+1:window=window[1:]return ans

T717:1bit和2bit字符

  • 回溯法
func isOneBitCharacter(bits []int) bool {if len(bits)==0 {return false}if len(bits)<2 {return true}if bits[len(bits)-2]==1 {return !isOneBitCharacterAssist(bits, len(bits)-3)}return true
}func isOneBitCharacterAssist(bits []int, index int) bool {if index==-1 {return true}if bits[index]==0 {if isOneBitCharacterAssist(bits, index-1) {return true}if index>0 && bits[index-1]==1 {if isOneBitCharacterAssist(bits, index-2) {return true}}} else if index>0 && bits[index]==1 && bits[index-1]==1 {if isOneBitCharacterAssist(bits, index-2) {return true}} else {return false}return false
}
  • 数学法
func isOneBitCharacter(bits []int) bool {step:=0for i:=0;i<len(bits);i+=step {if bits[i]==1 {step=2} else {step=1}}return step==1
}

T832:翻转图像

  • O(MN)时间复杂度
func flipAndInvertImage(A [][]int) [][]int {for i:=0;i<len(A);i++ {tmp:=A[i]for lo,hi:=0,len(tmp)-1;lo<=hi;lo,hi=lo+1,hi-1 {if lo==hi {tmp[lo]=1-tmp[lo]continue}if tmp[lo]!=tmp[hi] {continue} else {tmp[lo]=1-tmp[lo]tmp[hi]=1-tmp[hi]}}}return A
}

T232:用栈实现队列

  • 使用两个栈(两次反序)来达到正序
class MyQueue:def __init__(self):"""Initialize your data structure here."""self.stack1=[]self.stack2=[]def push(self, x: int) -> None:"""Push element x to the back of queue."""self.stack2.append(x)def pop(self) -> int:"""Removes the element from in front of queue and returns that element."""if len(self.stack1)==0:while len(self.stack2)>0:self.stack1.append(self.stack2.pop())if len(self.stack1)>0:return self.stack1.pop()return -1def peek(self) -> int:"""Get the front element."""if len(self.stack1)==0:while len(self.stack2)>0:self.stack1.append(self.stack2.pop())if len(self.stack1)>0:return self.stack1[-1]return -1def empty(self) -> bool:"""Returns whether the queue is empty."""return len(self.stack1)==0 and len(self.stack2)==0# Your MyQueue object will be instantiated and called as such:
# obj = MyQueue()
# obj.push(x)
# param_2 = obj.pop()
# param_3 = obj.peek()
# param_4 = obj.empty()

T225:用队列实现栈

  • 两个队列,使用O(N)时间复杂度互相转移实现反序
type MyStack struct {q1 []intq2 []intitem intlength int
}/** Initialize your data structure here. */
func Constructor() MyStack {return MyStack{[]int{}, []int{}, -1, 0}
}/** Push element x onto stack. */
func (this *MyStack) Push(x int)  {if len(this.q1)==0 {this.q1=append(this.q1, x)for idx:=0;idx<this.length;idx++ {x:=this.q2[0]this.q1=append(this.q1, x)this.q2=this.q2[1:]}} else if len(this.q2)==0 {this.q2=append(this.q2, x)for idx:=0;idx<this.length;idx++ {x:=this.q1[0]this.q2=append(this.q2, x)this.q1=this.q1[1:]}}this.item=xthis.length++
}/** Removes the element on top of the stack and returns that element. */
func (this *MyStack) Pop() int {var rVal intif len(this.q1)==0 {rVal=this.q2[0]this.q2=this.q2[1:]if len(this.q2)>0 {this.item=this.q2[0]}} else if len(this.q2)==0 {rVal=this.q1[0]this.q1=this.q1[1:]if len(this.q1)>0 {this.item=this.q1[0]}}this.length--return rVal
}/** Get the top element. */
func (this *MyStack) Top() int {return this.item
}/** Returns whether the stack is empty. */
func (this *MyStack) Empty() bool {return this.length==0
}/*** Your MyStack object will be instantiated and called as such:* obj := Constructor();* obj.Push(x);* param_2 := obj.Pop();* param_3 := obj.Top();* param_4 := obj.Empty();*/
  • 用一个队列,通过O(N)时间复杂度,类似插入排序实现反序
type MyStack struct {q1 []int
}/** Initialize your data structure here. */
func Constructor() MyStack {return MyStack{[]int{}}
}/** Push element x onto stack. */
func (this *MyStack) Push(x int)  {this.q1=append(this.q1, x)idx:=len(this.q1)-1for idx>0 {this.q1[idx], this.q1[idx-1]=this.q1[idx-1], this.q1[idx]idx--}
}/** Removes the element on top of the stack and returns that element. */
func (this *MyStack) Pop() int {x:=this.q1[0]this.q1=this.q1[1:]return x
}/** Get the top element. */
func (this *MyStack) Top() int {return this.q1[0]
}/** Returns whether the stack is empty. */
func (this *MyStack) Empty() bool {return len(this.q1)==0
}/*** Your MyStack object will be instantiated and called as such:* obj := Constructor();* obj.Push(x);* param_2 := obj.Pop();* param_3 := obj.Top();* param_4 := obj.Empty();*/

T20:有效的括号

  • 括号问题→栈
var memo map[byte]byte = map[byte]byte{')':'(', '}':'{', ']':'['}func isValid(s string) bool {stack:=[]byte{}for i:=0;i<len(s);i++ {if b, ok:=memo[s[i]];ok {if len(stack)==0 || stack[len(stack)-1]!=b {return false}stack=stack[:len(stack)-1]} else {stack=append(stack, s[i])}}if len(stack)>0 {return false}return true
}

T42:接雨水

  • sum=sum+min⁡{maxH[0:i],maxH[i:n−1]}−H[i]sum=sum+\min\{maxH_{[0:i]},maxH_{[i:n-1]}\}-H[i]sum=sum+min{maxH[0:i]​,maxH[i:n−1]​}−H[i]

  • 记忆化递归;O(N)时间复杂度;O(N)空间复杂度

func trap(height []int) int {memoL:=make([]int,len(height))for i:=0;i<len(memoL);i++ {memoL[i]=-1}memoR:=make([]int,len(height))for i:=0;i<len(memoR);i++ {memoR[i]=-1}sum:=0for i:=0;i<len(height);i++ {i1:=getMaxL(height, i, memoL)i2:=getMaxR(height, i, memoR)if i1>i2 {sum+=i2-height[i]} else {sum+=i1-height[i]}}return sum
}func getMaxL(height []int, loc int, memoL []int) int {if loc==0 {memoL[0]=height[0]return height[0]}if memoL[loc]!=-1 {return memoL[loc]}tmp:=getMaxL(height, loc-1, memoL)if tmp>height[loc] {memoL[loc]=tmpreturn tmp} else {memoL[loc]=height[loc]return height[loc]}
}
func getMaxR(height []int, loc int, memoR []int) int {if loc==len(height)-1 {memoR[loc]=height[loc]return height[loc]}if memoR[loc]!=-1 {return memoR[loc]}tmp:=getMaxR(height, loc+1, memoR)if tmp>height[loc] {memoR[loc]=tmpreturn tmp} else {memoR[loc]=height[loc]return height[loc]}
}
  • sum=sum+min⁡{maxH[0:lo],maxH[hi:n−1]}−H[i∈{lo,hi}]sum=sum+\min\{maxH_{[0:lo]},maxH_{[hi:n-1]}\}-H[i\in\{lo,hi\}]sum=sum+min{maxH[0:lo]​,maxH[hi:n−1]​}−H[i∈{lo,hi}]
  • 短板效应
  • O(N)时间复杂度;O(1)空间复杂度
func trap(height []int) int {if len(height)==0 {return 0}ans:=0left:=height[0]right:=height[len(height)-1]point1:=0point2:=len(height)-1for point1<point2 {if left<right {if height[point1+1]<=left {ans+=left-height[point1+1]} else {left=height[point1+1]}point1++} else {if height[point2-1]<=right {ans+=right-height[point2-1]} else {right=height[point2-1]}point2--}}return ans
}

※T224:基本计算器

  • 利用栈存储之前的计算结果
  • +,−,∗,/,(,)+, -, *, /, (, )+,−,∗,/,(,)
import "unicode"func calculate(s string) int {seq:=[]rune(s)idx:=0return calculateAssist(seq, &idx)
}func calculateAssist(seq []rune, idx *int) int {num:=0sign:='+'ans:=0stack:=[]int{}for *idx<len(seq) {c:=seq[*idx]if unicode.IsNumber(c) {num=num*10+int(c-'0')} else if c=='(' {(*idx)++num=calculateAssist(seq, idx)} else if !unicode.IsSpace(c) {    // 运算符或者')'或者'.'if c==')' {break}switch sign {case '+':stack=append(stack, num)case '-':stack=append(stack, -num)case '*':stack[len(stack)-1]*=numcase '/':stack[len(stack)-1]/=num}sign=cnum=0}(*idx)++}switch sign {    // 末尾数字case '+':stack=append(stack, num)case '-':stack=append(stack, -num)case '*':stack[len(stack)-1]*=numcase '/':stack[len(stack)-1]/=num}for i:=0;i<len(stack);i++ {ans+=stack[i]}return ans
}

T394:字符串解码

  • 十分类似于基本计算器的思路,即对括号的处理上
import "unicode"
import "bytes"func decodeString(s string) string {seq:=[]rune(s)idx:=0return decodeStringAssist(seq, &idx)
}func decodeStringAssist(seq []rune, idx *int) string {var tmp bytes.Buffernum:=0for *idx < len(seq) {c:=seq[*idx]if unicode.IsNumber(c) {    // 数字num=num*10+int(c-'0')} else if unicode.IsLetter(c) {    // 字母tmp.WriteRune(c)} else if c=='[' {    // '['代替了括号和乘法*(idx)++ans:=decodeStringAssist(seq, idx)for i:=0;i<num;i++ {tmp.WriteString(ans)}num=0} else {    // ']'表示终止break}*(idx)++}return tmp.String()
}

剑指04:二维数组中的查找

  • 相当于构造一棵二叉搜索树
func findNumberIn2DArray(matrix [][]int, target int) bool {i:=len(matrix)-1j:=0for i>=0 && j<len(matrix[0]) {if matrix[i][j]<target {j++} else if matrix[i][j]>target {i--} else {return true}}return false
}

※剑指45:把数组排成最小的数

  • 排序判断:任意交换相邻两个元素的位置都会使结果增大
  • 解决 3、32、34的顺序
func minNumber(nums []int) string {str_nums:=make([]string, len(nums))for i:=0;i<len(nums);i++ {str_nums[i]=strconv.Itoa(nums[i])}sort.Slice(str_nums, func(i int, j int) bool {return str_nums[i]+str_nums[j]<=str_nums[j]+str_nums[i]})return strings.Join(str_nums, "")
}

※剑指31:判断栈的压入序列、弹出序列

class Solution:def validateStackSequences(self, pushed: List[int], popped: List[int]) -> bool:stack, i = [], 0for num in pushed:stack.append(num) # num 入栈while stack and stack[-1] == popped[i]: # 循环判断与出栈stack.pop()i += 1return not stack
func validateStackSequences(pushed []int, popped []int) bool {stack:=[]int{}index:=0for i:=0;i<len(pushed);i++ {stack=append(stack, pushed[i])for len(stack)>0 && stack[len(stack)-1]==popped[index] {stack=stack[:len(stack)-1]index++}}if len(stack)==0 {return true}return false
}

※剑指51:数组中的逆序对

  • 基于归并排序思想
  • 在对数组进行归并排序的过程中,将无序变为有序的过程即可统计逆序对
func reversePairs(nums []int) int {tmp:=make([]int, len(nums))return mergeSort(nums, tmp, 0, len(nums)-1)
}func mergeSort(nums []int, tmp []int, lo int, hi int) int {if lo>=hi {return 0}mid:=(hi-lo)/2+lonum1:=mergeSort(nums, tmp, lo, mid)num2:=mergeSort(nums, tmp, mid+1, hi)if nums[mid]<=nums[mid+1] {    // 此时已有序return num1+num2}count:=0for i:=lo;i<=hi;i++ {tmp[i]=nums[i]}i:=loj:=mid+1for k:=lo;k<=hi;k++ {if i==mid+1 {nums[k]=tmp[j]j++} else if j==hi+1 {nums[k]=tmp[i]i++} else {if tmp[i]<=tmp[j] {    // 稳定排序nums[k]=tmp[i]i++} else {nums[k]=tmp[j]j++count+=mid-i+1}}}return num1+num2+count
}

T31:下一个排列

  • 若当前排列降序,则逆序输出
  • 否则找到第一个nums[i-1]<nums[i]的位置i,将nums[i-1]与nums[i:]上第一个比nums[i-1]大的元素交换位置,然后将nums[i:]逆序后输出
  • 时间复杂度O(N),空间复杂度O(1)
class Solution {public void nextPermutation(int[] nums) {if (nums.length<2) {return;}for (int point=nums.length-1;point>=1;point--) {if (nums[point-1]<nums[point]) {for (int index=nums.length-1;index>=point;index--) {if (nums[index]>nums[point-1]) {int tmp=nums[index];nums[index]=nums[point-1];nums[point-1]=tmp;reverse(nums, point, nums.length-1);return;}}}}reverse(nums, 0, nums.length-1);}public void reverse(int[] nums, int start, int end) {for (;start<end;start++,end--) {int tmp=nums[start];nums[start]=nums[end];nums[end]=tmp;}}
}

T60:第k个排列

  • 注意java中静态变量和实例变量都能用于预计算
  • 通过模除得到当前应取值
class Solution {private static int[] memo = produceNum();public String getPermutation(int n, int k) {k--;int num = n;char[] ans = new char[n];boolean[] set = new boolean[n];while (num>=1) {int index = k/memo[num-1];k %= memo[num-1];int tmp=0;for (int i=1;i<=n;i++) {if (set[i-1]) {continue;}if (tmp==index) {set[i-1]=true;ans[n-num]=(char)(i+'0');break;}tmp++;}num--;}return new String(ans);}private static int[] produceNum() {int[] memo = new int[10];memo[0]=1;for (int i=1;i<memo.length;i++) {memo[i]=i*memo[i-1];}return memo;}
}

T75:颜色分类

  • 0/1/2 三向切分快排
  • 如何指定基准值的具体值
  • 异或法实现swap对数组交换时当取同一个值时出错
class Solution {public void sortColors(int[] nums) {for (int i=0;i< nums.length;i++) {if (nums[i]==1) {swap(nums, 0, i);}}quickSortTri(nums);}public void quickSortTri(int[] nums) {int lo = 0;int idx = lo+1;int hi = nums.length-1;int tmp = nums[lo];while (idx <= hi) {int c = Integer.compare(nums[idx], tmp);if (c<0) {swap(nums, lo++, idx++);} else if (c>0) {swap(nums, hi--, idx);} else {idx++;}}}public void swap(int[] nums, int idx1, int idx2) {int tmp = nums[idx1];nums[idx1] = nums[idx2];nums[idx2] = tmp;}
}

T1207:独一无二的出现次数

class Solution {public boolean uniqueOccurrences(int[] arr) {HashMap<Integer, Integer> counter = new HashMap<>();for (Integer i:arr) {counter.put(i, counter.getOrDefault(i, 0)+1);}HashSet<Integer> set = new HashSet<>();for (Integer i :counter.values()) {if (set.contains(i)) {return false;}set.add(i);}return true;}
}

T80:删除排序数组中的重复项Ⅱ

  • 排序+双指针 去重
class Solution {public int removeDuplicates(int[] nums) {if (nums.length==0) {return 0;}int point1 = 0, point2 = 0;while (point1 < nums.length) {int count = 0;while (point1 < nums.length && nums[point1] == nums[point2]) {if (count==1) {    // 给出最高重复数nums[++point2] = nums[point1];}count++;point1++;}if (point1 < nums.length) {nums[++point2]=nums[point1];}}return point2+1;}
}

Leetcode(1)——数组、栈、队列相关推荐

  1. Leetcode刷题——栈与队列

    Leetcode刷题--栈与队列 一.栈与队列定义 二.Leetcode题目 1.用栈实现队列 2.用队列实现栈 一.栈与队列定义 栈:先进后出,栈提供push 和 pop 等等接口,所有元素必须符合 ...

  2. 常见数据结构和算法实现(排序/查找/数组/链表/栈/队列/树/递归/海量数据处理/图/位图/Java版数据结构)

    常见数据结构和算法实现(排序/查找/数组/链表/栈/队列/树/递归/海量数据处理/图/位图/Java版数据结构) 数据结构和算法作为程序员的基本功,一定得稳扎稳打的学习,我们常见的框架底层就是各类数据 ...

  3. 面试必备:高频算法题汇总「图文解析 + 教学视频 + 范例代码」必问之 链表 + 栈 + 队列 部分!

    链表 链表是最基本的数据结构,面试官也常常用链表来考察面试者的基本能力,而且链表相关的操作相对而言比较简单,也适合考察写代码的能力.链表的操作也离不开指针,指针又很容易导致出错. 综合多方面的原因,链 ...

  4. 黑马程序员 C语言数据结构与算法之线性表(链表/栈/队列/顺序表)

    C语言 链表基础知识清晰讲解(黑马) 讲的蛮好,就是音质不太好,有时听不清讲的啥! [黑马]数据结构与算法之线性表(链表/栈/队列/顺序表)[配套源码 嘛蛋,看错了,这是java的... 文章目录 链 ...

  5. 数组模拟队列(代码实现)

    数据结构可分为两种,第一种是线性结构,第二种是非线性结构,线性结构又分为连续存储和链表存储. 常见的线性结构有数组,链表,队列,栈: 以下是数组模拟队列的实现(队列特点就是先进先出): //数组模拟队 ...

  6. (链表 栈 队列 递归)

    文章目录 链表 反转链表 删除点链表中给定值的结点 栈和队列 双向链表实现栈和队列 数组实现队列 获取栈的最小值 用两个栈实现一个队列 用两个队列实现一个栈 递归 链表 反转链表 (反转单链表 反转双 ...

  7. 【Java数据结构与算法】第一章 稀疏数组和队列

    第一章 稀疏数组和队列 文章目录 第一章 稀疏数组和队列 一.线性结构和非线性结构 1.线性结构 2.非线性结构 二.稀疏数组 三.队列 1.队列 2.环形队列 一.线性结构和非线性结构 1.线性结构 ...

  8. java中定义一个栈容器_Java 容器之 Connection栈队列及一些常用

    集合家族图 ---|Collection: 单列集合 ---|List: 有存储顺序 , 可重复 ---|ArrayList: 数组实现 , 查找快 , 增删慢 ---|LinkedList: 链表实 ...

  9. freemarker 数组转字符串_TypeScript 实战算法系列(一):实现数组栈与对象栈

    本文由图雀社区认证作者 神奇的程序员 写作而成,图雀社区将连载其TypeScript 实战算法系列,点击阅读原文查看作者的掘金链接,感谢作者的优质输出,让我们的技术世界变得更加美好? 前言 栈作为一种 ...

  10. Java 容器之 Connection栈队列及一些常用

    集合家族图 ---|Collection: 单列集合---|List: 有存储顺序 , 可重复---|ArrayList: 数组实现 , 查找快 , 增删慢 ---|LinkedList: 链表实现 ...

最新文章

  1. Windows下FFmpeg高速入门
  2. 在当当买了python怎么下载源代码-爬虫实战一:爬取当当网所有 Python 书籍
  3. python项目实战:获取本机所有IP地址的方法
  4. 用来处理python字典的方法_python字典的常用方法总结
  5. jupyter notebook和python有什么区别_Jupyter Notebook 有哪些奇技淫巧?
  6. java xml二进制流传输_XML中二进制数据的处理方法
  7. 软件定义重划边界——IT就是把复杂东西简单化
  8. .NET简谈自定义事务资源管理器
  9. Arcgis Javascript API 开发笔记
  10. 最新b站后端源码,仅学习使用,请勿用于商业用途,如拿去非法使用与本人无关!
  11. 富士胶片滤镜人像调色预设PS插件
  12. 使用YYLabel做文本竖向展示
  13. 使用Python一键获取百度网盘提取码
  14. 有理数加法C语言pta,有理数
  15. 编译java源文件(在cmd下编译)傻瓜式教学
  16. 如何写好项目规划和方案设计文档
  17. 大数据助力普惠金融发展
  18. matlab怎么把音频变成信号_利用MATLAB软件对音频信号进行频谱分析及处理.doc
  19. 春招必看一位老学长的真实互联网校招求职心路历程~
  20. A. One and Two

热门文章

  1. 不知道照片一键换天空的软件有什么?分享这几款制作软件
  2. stm32 MDK debug调试方法
  3. 5年测试开发工程师感悟——写给还在迷茫中的朋友
  4. lorawan协议网关如何选择?-东胜物联
  5. Js 几种刷新页面最快的方法
  6. 鸟哥的Linux私房菜-第七章、Linux 磁盘与文件系统管理
  7. 阿里17实习生编程-数组四等分
  8. PB编辑器里怎么查看代码行数
  9. Unity Shader - Built-in管线下优化 multi_compile_fwdbase、multi_compile_fog 变体
  10. Interview Questions and Ans