python coding with ChatGPT 打卡第6天| 哈希表:四数相加、赎金信、三数之和、四数之和

系列文章
python coding with ChatGPT 打卡第1天| 二分查找、移除元素
python coding with ChatGPT 打卡第2天| 双指针、滑动窗口、螺旋矩阵
python coding with ChatGPT 打卡第3天| 移除链表、设计链表、反转链表
python coding with ChatGPT 打卡第4天| 链表其他操作:两两交换、删除倒数第N个节点 链表相交 环形链表
python coding with ChatGPT 打卡第5天| 哈希表:有效字母异位词、两个数组的交集、快乐数、两数之和

四数相加II

Key Points

  1. 用哈希表来降低时间复杂度

相关题目

454. 四数相加II

视频讲解

map使用技巧

重点分析

在这里插入图片描述暴力解法:

def fourSumCount(nums1, nums2, nums3, nums4):
    count = 0
    for val1 in nums1:
        for val2 in nums2:
            for val3 in nums3:
                for val4 in nums4:
                    if val1 + val2 + val3 + val4 == 0:
                        count += 1

    return count

使用字典

def fourSumCount(nums1, nums2, nums3, nums4):
    record = dict()
    count = 0

    for val1 in nums1:
        for val2 in nums2:
            val_sum1 = val1 + val2
            if val_sum1 in record:
                record[val_sum1] += 1
            else:
                record[val_sum1] = 1  

    for val3 in nums3:
        for val4 in nums4:
            val_sum2 = val3 + val4
            val_target = 0 - val_sum2
            if val_target in record:
                count += record[val_target]

    return count

更简洁的写法:

if val_sum1 in record:
    record[val_sum1] += 1
else:
    record[val_sum1] = 1
    
# 可以直接写成1行
record[val_sum1] = record.get(val_sum1, 0) + 1  

赎金信

Key Points

  1. 字符串只含有小写英文字母,所以可以采用数组

相关题目

383. 赎金信

重点分析

方法1:字典法

def canConstruct(ransomNote, magazine):
    record = dict()
    for char in magazine:
        record[char] = record.get(char, 0) + 1

    for char in ransomNote:
        if char in record:
            record[char] -= 1
            if record[char] < 0:
                return False
        else:
            return False
    return True

方法2:数组法

def canConstruct(ransomNote, magazine):
    record = [0]*26

    for char in magazine:
        record[ord(char)-ord('a')] +=1

    for char in ransomNote:
        record[ord(char)-ord('a')] -= 1

    if all(x>=0 for x in record):
        return True
    return False

三数之和

Key Points

  1. 双指针法
    在这里插入图片描述

相关题目

15. 三数之和

视频讲解

梦破碎的地方

重点分析

在这里插入图片描述

def threeSum(nums):
    res = []
    nums.sort()

    for i in range(len(nums)):
        if i > 0:
            if nums[i] == nums[i-1]:
                continue

        left = i + 1
        right = len(nums)-1

        while left < right:
            if nums[i] + nums[left] + nums[right] == 0:
                res.append([nums[i], nums[left], nums[right]])
                left += 1
                while left < len(nums)-1 and nums[left] == nums[left-1]:
                    left += 1

                right -= 1
                while right > 0 and nums[right] == nums[right+1]:
                    right -= 1

            elif nums[i] + nums[left] + nums[right] > 0:
                right -= 1

            else:
                left += 1
    return res

四数之和

Key Points

四数之和,和15.三数之和是一个思路,都是使用双指针法, 基本解法就是在15.三数之和的基础上再套一层for循环。

相关题目

18. 四数之和

视频讲解

难在去重和剪枝

其实不做剪枝也可以通过,我的代码就没有写剪枝的内容

重点分析

def fourSum(nums, target):
    res = []
    nums.sort()

    for i in range(len(nums)):
        if i > 0:
            if nums[i] == nums[i-1]:
                continue
        for k in range(i+1,len(nums)-1):
            if k > i+1:
                if nums[k] == nums[k-1]:
                    continue
            left = k + 1
            right = len(nums) - 1
            while left < right:
                if nums[i] + nums[k] + nums[left] + nums[right] == target:
                    res.append([nums[i], nums[k], nums[left], nums[right]])
                    left += 1
                    right -= 1
                    while left < len(nums)-1 and nums[left] == nums[left-1]:
                        left += 1
                    while right > 0 and nums[right] == nums[right+1]:
                        right -= 1
                elif nums[i] + nums[k] + nums[left] + nums[right] > target:
                    right -= 1
                else:
                    left += 1

    return res

在这里插入图片描述

拓展

一样的道理,能解决四数之和 那么五数之和、六数之和、N数之和呢?

四数之和的双指针解法是两层for循环nums[k] + nums[i]为确定值,依然是循环内有left和right下标作为双指针,找出nums[k] + nums[i] + nums[left] + nums[right] == target的情况,三数之和的时间复杂度是O(n2),四数之和的时间复杂度是O(n3) 。
因此,对于三数之和双指针法就是将原本暴力O(n3)的解法,降为O(n2)的解法,四数之和的双指针解法就是将原本暴力O(n4)的解法,降为O(n3)的解法。

那么一样的道理,五数之和、六数之和等等都采用这种解法。

之前我们讲过哈希表的经典题目:454.四数相加II相对于本题简单很多,因为本题是要求在一个集合中找出四个数相加等于target,同时四元组不能重复。而454.四数相加II是四个独立的数组,只要找到A[i] + B[j] + C[k] + D[l] = 0就可以,不用考虑有重复的四个元素相加等于0的情况,所以相对于本题还是简单了不少!


双指针总结

双指针法将时间复杂度:O(n2)的解法优化为 O(n)的解法。也就是降一个数量级,题目如下:

27. 移除元素
15. 三数之和
18. 四数之和

题目详解

链表相关:

206. 反转链表
19. 删除链表的倒数第N个节点
160. 链表相交
142. 环形链表II

题目详解1
题目详解2

  • 32
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值