Leetcode(1)——数组、栈、队列
格式:
题号+题名+简单思路+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 / 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_start
和max_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)——数组、栈、队列相关推荐
- Leetcode刷题——栈与队列
Leetcode刷题--栈与队列 一.栈与队列定义 二.Leetcode题目 1.用栈实现队列 2.用队列实现栈 一.栈与队列定义 栈:先进后出,栈提供push 和 pop 等等接口,所有元素必须符合 ...
- 常见数据结构和算法实现(排序/查找/数组/链表/栈/队列/树/递归/海量数据处理/图/位图/Java版数据结构)
常见数据结构和算法实现(排序/查找/数组/链表/栈/队列/树/递归/海量数据处理/图/位图/Java版数据结构) 数据结构和算法作为程序员的基本功,一定得稳扎稳打的学习,我们常见的框架底层就是各类数据 ...
- 面试必备:高频算法题汇总「图文解析 + 教学视频 + 范例代码」必问之 链表 + 栈 + 队列 部分!
链表 链表是最基本的数据结构,面试官也常常用链表来考察面试者的基本能力,而且链表相关的操作相对而言比较简单,也适合考察写代码的能力.链表的操作也离不开指针,指针又很容易导致出错. 综合多方面的原因,链 ...
- 黑马程序员 C语言数据结构与算法之线性表(链表/栈/队列/顺序表)
C语言 链表基础知识清晰讲解(黑马) 讲的蛮好,就是音质不太好,有时听不清讲的啥! [黑马]数据结构与算法之线性表(链表/栈/队列/顺序表)[配套源码 嘛蛋,看错了,这是java的... 文章目录 链 ...
- 数组模拟队列(代码实现)
数据结构可分为两种,第一种是线性结构,第二种是非线性结构,线性结构又分为连续存储和链表存储. 常见的线性结构有数组,链表,队列,栈: 以下是数组模拟队列的实现(队列特点就是先进先出): //数组模拟队 ...
- (链表 栈 队列 递归)
文章目录 链表 反转链表 删除点链表中给定值的结点 栈和队列 双向链表实现栈和队列 数组实现队列 获取栈的最小值 用两个栈实现一个队列 用两个队列实现一个栈 递归 链表 反转链表 (反转单链表 反转双 ...
- 【Java数据结构与算法】第一章 稀疏数组和队列
第一章 稀疏数组和队列 文章目录 第一章 稀疏数组和队列 一.线性结构和非线性结构 1.线性结构 2.非线性结构 二.稀疏数组 三.队列 1.队列 2.环形队列 一.线性结构和非线性结构 1.线性结构 ...
- java中定义一个栈容器_Java 容器之 Connection栈队列及一些常用
集合家族图 ---|Collection: 单列集合 ---|List: 有存储顺序 , 可重复 ---|ArrayList: 数组实现 , 查找快 , 增删慢 ---|LinkedList: 链表实 ...
- freemarker 数组转字符串_TypeScript 实战算法系列(一):实现数组栈与对象栈
本文由图雀社区认证作者 神奇的程序员 写作而成,图雀社区将连载其TypeScript 实战算法系列,点击阅读原文查看作者的掘金链接,感谢作者的优质输出,让我们的技术世界变得更加美好? 前言 栈作为一种 ...
- Java 容器之 Connection栈队列及一些常用
集合家族图 ---|Collection: 单列集合---|List: 有存储顺序 , 可重复---|ArrayList: 数组实现 , 查找快 , 增删慢 ---|LinkedList: 链表实现 ...
最新文章
- Windows下FFmpeg高速入门
- 在当当买了python怎么下载源代码-爬虫实战一:爬取当当网所有 Python 书籍
- python项目实战:获取本机所有IP地址的方法
- 用来处理python字典的方法_python字典的常用方法总结
- jupyter notebook和python有什么区别_Jupyter Notebook 有哪些奇技淫巧?
- java xml二进制流传输_XML中二进制数据的处理方法
- 软件定义重划边界——IT就是把复杂东西简单化
- .NET简谈自定义事务资源管理器
- Arcgis Javascript API 开发笔记
- 最新b站后端源码,仅学习使用,请勿用于商业用途,如拿去非法使用与本人无关!
- 富士胶片滤镜人像调色预设PS插件
- 使用YYLabel做文本竖向展示
- 使用Python一键获取百度网盘提取码
- 有理数加法C语言pta,有理数
- 编译java源文件(在cmd下编译)傻瓜式教学
- 如何写好项目规划和方案设计文档
- 大数据助力普惠金融发展
- matlab怎么把音频变成信号_利用MATLAB软件对音频信号进行频谱分析及处理.doc
- 春招必看一位老学长的真实互联网校招求职心路历程~
- A. One and Two
热门文章
- 不知道照片一键换天空的软件有什么?分享这几款制作软件
- stm32 MDK debug调试方法
- 5年测试开发工程师感悟——写给还在迷茫中的朋友
- lorawan协议网关如何选择?-东胜物联
- Js 几种刷新页面最快的方法
- 鸟哥的Linux私房菜-第七章、Linux 磁盘与文件系统管理
- 阿里17实习生编程-数组四等分
- PB编辑器里怎么查看代码行数
- Unity Shader - Built-in管线下优化 multi_compile_fwdbase、multi_compile_fog 变体
- Interview Questions and Ans