functwoSum(nums []int, target int)[]int{m :=make(map[int]int,0)for i :=0; i <len(nums); i++{if_, exist := m[target-nums[i]]; exist {return[]int{i, m[target-nums[i]]}}else{m[nums[i]]= i}}return[]int{}}
字母異位詞分組
funcgroupAnagrams(strs []string)[][]string{m :=make(map[string][]string)for_, str :=range strs {count :=make([]int,26)for i :=0; i <len(str); i++{count[str[i]-'a']++}// 把 count 序列化成 keykey :=""for i, c :=range count {if c >0{// []byte can not use as map's key, use word+num insteadkey +=string('a'+i)+ strconv.Itoa(c)}}m[key]=append(m[key], str)}result :=make([][]string,0,len(m))for_, v :=range m {result =append(result, v)}return result
}funcgroupAnagrams(strs []string)[][]string{// 在 Go 里,數組是值類型,不是引用類型mp :=map[[26]int][]string{}for_, str :=range strs {cnt :=[26]int{}for_, b :=range str {cnt[b-'a']++}mp[cnt]=append(mp[cnt], str)}ans :=make([][]string,0,len(mp))for_, v :=range mp {ans =append(ans, v)}return ans
}
最長連續序列
funclongestConsecutive(nums []int)int{m :=make(map[int]bool)for_, v :=range nums {m[v]=true}longest :=0// using map can avoid large number of redundant comparisonsfor v :=range m {// 判斷當前數字是不是 "序列起點",這招超萬能// 很多 LeetCode 連續區間題目都能套用這個模板// 稀疏矩陣的時候,可以遍歷原map(注意不是原數組,不然重復判斷的情況仍會存在)// 找到比這個數小不在map里,這個數就看作是起點,不斷找到比他大的數在不在map中,就能少了很多無效判斷if!m[v-1]{length :=1n := vfor m[n+1]{n++length++}if length > longest {longest = length}}}return longest
}
移動零
funcmoveZeroes(nums []int){// 雙指針的思路,做的時候容易過分重視 i 和 j 指針// i 指針是指向非零元素應該放入的位置,而 j 指針應該去尋找非零元素把其放入 i 指針所指向的位置,一次遍歷// index at i is the num not equal to zero// index at j is the num equal to zero// i for storing the num not zero, j for scanningleft, right, n :=0,0,len(nums)for right < n {if nums[right]!=0{nums[left], nums[right]= nums[right], nums[left]left++}right++}}// 另一思路:把所有非零元素左移,后面全填充 0
盛水最多的容器
// 貪心,比當前指針大的才需要移動// 為什么移動較低指針是正確的?// 因為當前最大的盛水量是由寬度和最短板高度決定的,如果移動較長的板,無論是高了還是矮了,最大盛水量都是由短的木板來決定,但是寬度已經減少了,所以移動較長的木板并不會使我們的盛水容量增加// 但是移動短的木板,雖然我們的寬度減少了,但是由于木板可能會變長,所以我們的盛水容量可能會變大,所以移動短的木板才是正確的funcmaxArea(height []int)int{max :=0i, j :=0,len(height)-1for i < j {area :=(j - i)*min(height[i], height[j])if area > max {max = area}// if move the higher, area must be smaller, because the area depends on the shorter side// but if move the shorter, area may be largerif height[i]<= height[j]{i++}else{j--}}return max
}
三數之和
functhreeSum(nums []int)[][]int{l :=len(nums)result :=make([][]int,0)sort.Ints(nums)// pay attention to the loop termination conditionfor i :=0; i < l-2; i++{// deduplicationif i >0&& nums[i]== nums[i-1]{continue}left, right := i+1, l-1for left < right {sum := nums[i]+ nums[left]+ nums[right]if sum ==0{result =append(result,[]int{nums[i], nums[left], nums[right]})// skip the repeated elements on the leftfor left < right && nums[left]== nums[left+1]{left++}// skip the repeated elements on the rightfor left < right && nums[right]== nums[right-1]{right--}left++right--}elseif sum <0{left++}else{right--}}}return result
}
接雨水
在這里插入代碼片
無重復字符的最長子串
funclengthOfLongestSubstring(s string)int{result :=0mp :=make(map[byte]int)length :=len(s)l :=0for i :=0; i < length; i++{// if the index is greater than or equal to the left boundary,// it can be included in the sliding window,// thus eliminating the need to delete elements from the mapif index, exist := mp[s[i]]; exist && index >= l {l = index +1}if result < i-l+1{result = i - l +1}mp[s[i]]= i}return result
}funclengthOfLongestSubstring(s string)(ans int){cnt :=[128]int{}// 也可以用 map,這里為了效率用的數組left :=0for right, c :=range s {cnt[c]++for cnt[c]>1{// 窗口內有重復字母cnt[s[left]]--// 移除窗口左端點字母left++// 縮小窗口}ans =max(ans, right-left+1)// 更新窗口長度最大值}return ans
}
找到字符串中所有字母異位詞
funcfindAnagrams(s string, p string)[]int{result :=make([]int,0)// using map is actually not very efficient// an optimization idea is to switch to array countingms, mp :=make(map[byte]int),make(map[byte]int)lenp :=len(p)// comparison function moved insidemapsEqual :=func(a, b map[byte]int)bool{iflen(a)!=len(b){returnfalse}for k, v :=range a {if bv, ok := b[k];!ok || bv != v {returnfalse}}returntrue}for i :=0; i < lenp; i++{mp[p[i]]++}for i :=0; i <len(s); i++{ms[s[i]]++if i < lenp-1{continue}ifmapsEqual(ms, mp){result =append(result, i-lenp+1)}// cannot directly delete the key// if the character appears multiple times in the window, it will cause counting errors// cannot simply subtract one from the count, as the presence of a key can lead to incorrect judgments// the correct approach is to subtract 1. If it is reduced to 0, then delete:ms[s[i-lenp+1]]--if ms[s[i-lenp+1]]==0{delete(ms, s[i-lenp+1])}}return result
}
funcdailyTemperatures(temperatures []int)[]int{stack :=make([]int,0)stack =append(stack,0)result :=make([]int,len(temperatures))for i :=1; i <len(temperatures); i++{// 注意這里要判斷棧是否為空,否則stack[len(stack)-1]會報錯forlen(stack)>0&& temperatures[i]> temperatures[stack[len(stack)-1]]{result[stack[len(stack)-1]]= i - stack[len(stack)-1]stack = stack[:len(stack)-1]}// 存儲的是索引值,方便后續計算距離stack =append(stack, i)}return result
}
柱狀圖中最大的矩形
數組中的第K個最大元素
前 K 個高頻元素
數據流的中位數
買賣股票的最佳時機
跳躍游戲
跳躍游戲 II
劃分字母區間
爬樓梯
楊輝三角
打家劫舍
完全平方數
零錢兌換
單詞拆分
最長遞增子序列
乘積最大子數組
分割等和子集
最長有效括號
不同路徑
最小路徑和
最長回文子串
最長公共子序列
編輯距離
只出現一次的數字
// 必須設計并實現線性時間復雜度的算法來解決此問題,且該算法只使用常量額外空間// 大部分都是出現2次,聯想到位運算:異或(XOR)運算// a ^ a = 0// 0 ^ a = a// a ^ 0 = afuncsingleNumber(nums []int)int{result :=0for_, v :=range nums {result ^= v}return result
}
funcsortColors(nums []int){red0, white1, blue2 :=0,0,0// 統計每個顏色的數量for_, v :=range nums {if v ==0{red0++}elseif v ==1{white1++}elseif v ==2{blue2++}}// 重寫數組for i :=0; i < red0; i++{nums[i]=0}for i := red0; i < red0+white1; i++{nums[i]=1}for i := red0 + white1; i < red0+white1+blue2; i++{nums[i]=2}}// 僅使用常數空間的一趟掃描算法