代码随想录Day7

454. 四数相加 II - 力扣(LeetCode)

四数和两数之和相比还是有些变化

func fourSumCount(nums1 []int, nums2 []int, nums3 []int, nums4 []int) (ans int) {
    countAB := map[int]int{}
    for _, v := range nums1 {
        for _, w := range nums2 {
            countAB[v+w]++
        }
    }
    for _, v := range nums3 {
        for _, w := range nums4 {
            ans += countAB[-v-w]
        }
    }
    return
}

383. 赎金信 - 力扣(LeetCode)

赎金信用一个数组做哈希即可

func canConstruct(ransomNote string, magazine string) bool {
    words := make([]int, 26)
    for i := 0; i < len(magazine); i++ {
        words[magazine[i]-'a']++
    }
    for i := 0; i < len(ransomNote); i++ {
        words[ransomNote[i]-'a']--
    }
    for i := 0; i < 26; i++ {
        if words[i] < 0 {
            return false
        }
    }
    return true
}

15. 三数之和 - 力扣(LeetCode)

枚举循环好复杂

func threeSum(nums []int) [][]int {
    n := len(nums)
    sort.Ints(nums)
    ans := make([][]int, 0)

    // 枚举 a
    for first := 0; first < n; first++ {
        // 如果和上一个数字相同,就跳过
        if first > 0 && nums[first] == nums[first-1] {
            continue
        }
        third := n-1
        target := -1 * nums[first]
        // 枚举 b
        for second := first + 1; second < n; second++ {
            // 需要和上一次枚举的数不同
            if second > first +1 && nums[second] == nums[second-1] {
                continue
            }
            for second < third && nums[second] + nums[third] > target {
                third--
            }
            if second == third {
                break
            }
            if nums[second] + nums[third] == target {
                ans = append(ans, []int{nums[first], nums[second], nums[third]})
            }
        }
    }
    return ans
}

18. 四数之和 - 力扣(LeetCode)

不想再写这种循环了

func fourSum(nums []int, target int) (ans [][]int) {
    sort.Ints(nums)
    n := len(nums)
    for a := 0; a < n-3; a++ { // 枚举第一个数
        x := nums[a]
        if a > 0 && x == nums[a-1] { // 跳过重复数字
            continue
        }
        if x+nums[a+1]+nums[a+2]+nums[a+3] > target { // 优化一
            break
        }
        if x+nums[n-3]+nums[n-2]+nums[n-1] < target { // 优化二
            continue
        }
        for b := a + 1; b < n-2; b++ { // 枚举第二个数
            y := nums[b]
            if b > a+1 && y == nums[b-1] { // 跳过重复数字
                continue
            }
            if x+y+nums[b+1]+nums[b+2] > target { // 优化一
                break
            }
            if x+y+nums[n-2]+nums[n-1] < target { // 优化二
                continue
            }
            c, d := b+1, n-1
            for c < d { // 双指针枚举第三个数和第四个数
                s := x + y + nums[c] + nums[d] // 四数之和
                if s > target {
                    d--
                } else if s < target {
                    c++
                } else {
                    ans = append(ans, []int{x, y, nums[c], nums[d]})
                    for c++; c < d && nums[c] == nums[c-1]; c++ {} // 跳过重复数字
                    for d--; d > c && nums[d] == nums[d+1]; d-- {} // 跳过重复数字
                }
            }
        }
    }
    return
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值