[代码随想录]Day06-哈希表 part02
1.[代码随想录]Day01-数组part012.[代码随想录]Day02-数组part02
3.[代码随想录]Day06-哈希表 part02
4.[代码随想录]Day05-哈希表 part015.[代码随想录]Day04-链表part026.[代码随想录]Day03-链表part017.[代码随想录]Day14-二叉树part038.[代码随想录]Day13-二叉树part029.[代码随想录]Day12-二叉树part0110.[代码随想录]Day11-栈与队列part0311.[代码随想录]Day10-栈与队列part0212.[代码随想录]Day09-栈与队列part0113.[代码随想录]Day08-字符串 part0214.[代码随想录]Day07-字符串 part0115.[代码随想录]Day30-贪心算法part0416.[代码随想录]Day29-贪心算法part0317.[代码随想录]Day28-贪心算法part0218.[代码随想录]Day27-贪心算法part0119.[代码随想录]Day26-回溯算法part0620.[代码随想录]Day25-回溯算法part0521.[代码随想录]Day24-回溯算法part0422.[代码随想录]Day23-回溯算法part0323.[代码随想录]Day22-回溯算法part0224.[代码随想录]Day21-回溯算法part0125.[代码随想录]Day20-二叉树part0926.[代码随想录]Day19-二叉树part0827.[代码随想录]Day18-二叉树part0728.[代码随想录]Day17-二叉树part0629.[代码随想录]Day16-二叉树part0530.[代码随想录]Day15-二叉树part0431.[代码随想录]Day52-单调栈part0332.[代码随想录]Day51-单调栈part0233.[代码随想录]Day50-单调栈part0134.[代码随想录]Day49-动态规划part1735.[代码随想录]Day48-动态规划part1636.[代码随想录]Day47-动态规划part1537.[代码随想录]Day46-动态规划part1438.[代码随想录]Day45-动态规划part1339.[代码随想录]Day44-动态规划part1240.[代码随想录]Day43-动态规划part1141.[代码随想录]Day42-动态规划part1042.[代码随想录]Day41-动态规划part0943.[代码随想录]Day40-动态规划part0844.[代码随想录]Day39-动态规划part0745.[代码随想录]Day38-动态规划part0646.[代码随想录]Day37-动态规划part0547.[代码随想录]Day36-动态规划part0448.[代码随想录]Day35-动态规划part0349.[代码随想录]Day34-动态规划part0250.[代码随想录]Day33-动态规划part0151.[代码随想录]Day32-贪心算法part0652.[代码随想录]Day31-贪心算法part05题目:454. 四数相加 II
思路:
首先,因为下标不同,因此相同的序列可能会出现很多次。
A + B + C + D = 0,那么当知道保存了A+B的和之后,就看有没有A + B = 0 - C - D了。
代码:
func fourSumCount(nums1 []int, nums2 []int, nums3 []int, nums4 []int) int {
res := 0 // 记录个数
maps := make(map[int]int, 0)
for _, v1 := range nums1 { // 把A和B的和全都放在map中
for _, v2 := range nums2 {
maps[v1 + v2]++ // 要记录次数
}
}
for _, v3 := range nums3 { // 计算C和D的和 看看map里有没有-(v3+v4)
for _, v4 := range nums4 {
res += maps[-v3-v4] // 有几个加几次
}
}
return res
}
参考:
题目:383. 赎金信
思路:
这个和昨天的异构词是一样的思路,唯一不同的地方是异构词是每个字母的个数都一样,这道题是可以少用但不能多用。
代码:
func canConstruct(ransomNote string, magazine string) bool {
t := [26]int{} // 存26个字母
for _, v := range magazine {
t[v-'a'] ++ // 每个字母出现次数
}
for _, v := range ransomNote {
ch := v - 'a'
if t[ch] != 0 {
t[ch]-- // 只能用一次
continue
}
return false // 不够用了
}
return true
}
参考:
题目:15. 三数之和
思路:
这道题用哈希最大的一个问题是需要去重,这里用双指针做。
首先固定一个位置即i,剩下两个指针为j和k起始位置分别是i+1以及len-1,在计算和的时候,因为i是不变的,只有j和k变化:
- 当sum大于0时,那么值就需要缩小,因此右指针向左,并且[j,k)中的所有指向的元素加上k指向的元素和都是大于sum的,因此后续无需再考虑k的位置
- 当sum小于0时,那么值就需要增大,因此左指针向右,并且(j,k]中的所有指向的元素加上j指向的元素和都是小于sum的,因此后续无需再考虑k的位置
说明什么,说明这是一个贪心,你只需要看当前是大是小来移动指针即可。注意一点,在范围之外的元素是已经操作完了的,不用担心。分治。
一个剪枝:
- 当
nums[i]>0
时,nums[j]
和nums[k]
必然都是大于0,和一定大于0,后续也是如此,所以直接break掉
三个元素都要写一个去重,如果和上一个元素一样直接continue。
代码:
双指针解决
func threeSum(nums []int) [][]int {
lens := len(nums)
res := [][]int{} // 结果
if lens < 3 { // 不足三个元素直接返回空
return [][]int{}
}
sort.Ints(nums) // 要先排序一下
for i := 0 ; i < lens-2; i++ { // 注意是 i < lens - 2
if nums[i] > 0 { // 剪枝1
break
}
if i > 0 && nums[i-1] == nums[i] { // 去重i
continue
}
j, k := i + 1, lens - 1 // 两个指针
for j < k {
n1, n2, n3 := nums[i], nums[j], nums[k]
sum := n1 + n2 + n3
if sum < 0 { // 左指针向右
j++
}else if sum > 0 { // 右指针向左
k--
}else if sum == 0{
res = append(res, []int{n1,n2,n3})
for j < k && nums[j] == n2 { // 去重j
j++
}
for j < k && nums[k] == n3 { // 去重k
k--
}
}
}
}
return res
}
参考:
题目:18. 四数之和
思路:
上面是三维变二维,这个是四维变三维,思路都是一样的。
抓住一个重点——去重,每一个元素都需要进行去重操作。因为这个题不是和为0而是固定的target因此不能简单的通过第一个元素去剪枝,而是四个元素同时使用才能剪枝。
代码:
func fourSum(nums []int, target int) [][]int {
lens := len(nums)
res := [][]int{}
if lens < 4 {
return [][]int{}
}
sort.Ints(nums)
for i := 0; i < lens - 3; i++ {
if i > 0 && nums[i] == nums[i-1] { // 去重i
continue
}
for j := i + 1; j < lens - 2; j++ {
if j > i + 1 && nums[j] == nums[j-1] { // 去重j
continue
}
l, r := j + 1, lens - 1
for l < r {
n1, n2, n3, n4 := nums[i], nums[j], nums[l], nums[r]
sum := n1 + n2 + n3 + n4
if sum < target {
l ++
}
if sum > target {
r --
}
if sum == target {
res = append(res, []int{n1,n2,n3,n4})
for l < r && nums[l] == n3 { // 去重l
l ++
}
for l < r && nums[r] == n4 { // 去重r
r --
}
}
}
}
}
return res
}
参考:
合集:
代码随想录
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理