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}}// 仅使用常数空间的一趟扫描算法