代码随想录算法训练营第七天| 454.四数相加II、383.赎金信、15.三数之和、18.四数之和

一、今日任务

二、四数相加II

2.1 题目:454. 四数相加 II

2.2 解题过程

拿到题目的第一个反应就是先暴力。四个循环,显然肯定不是最优,但是,先写出来吧。

class Solution(object):
    def fourSumCount(self, nums1, nums2, nums3, nums4):
        """
        :type nums1: List[int]
        :type nums2: List[int]
        :type nums3: List[int]
        :type nums4: List[int]
        :rtype: int
        """
        sum = 0
        n = len(nums1)
        for i in nums1:
            for j in nums2:
                for x in nums3:
                    for y in nums4:
                        if i+j+x+y == 0:
                            sum += 1
        return sum

不出意料地超时,按照哈希表的思路,在前面的两数之和里是利用一个找一个。

计划优化的地方有,先讲四个数组存入四个哈希表。在分别计算nums1+nums2,nums3+nums4的和加入新的哈希表。再遍历一次寻找符合条件的。勉强满足时间限制。

class Solution(object):
    def fourSumCount(self, nums1, nums2, nums3, nums4):
        """
        :type nums1: List[int]
        :type nums2: List[int]
        :type nums3: List[int]
        :type nums4: List[int]
        :rtype: int
        """
        record1 = {}
        for index, val in enumerate(nums1):
            if val in record1.keys():
                record1[val].append(index)
            else:
                record1[val] = [index]
        record2 = {}
        for index, val in enumerate(nums2):
            if val in record2.keys():
                record2[val].append(index)
            else:
                record2[val] = [index]
        record3 = {}
        for index, val in enumerate(nums3):
            if val in record3.keys():
                record3[val].append(index)
            else:
                record3[val] = [index]
        record4 = {}
        for index, val in enumerate(nums4):
            if val in record4.keys():
                record4[val].append(index)
            else:
                record4[val] = [index]
        sum_record12 = {}
        sum_record34 = {}
        for i in record1.keys():
            for j in record2.keys():
                sum12 = i + j
                if sum12 in sum_record12.keys():
                    sum_record12[sum12] += len(record1[i]) * len(record2[j])
                else:
                    sum_record12[sum12] = len(record1[i]) * len(record2[j])
        for x in record3.keys():
            for y in record4.keys():
                sum34 = x + y
                if sum34 in sum_record34.keys():
                    sum_record34[sum34] += len(record3[x]) * len(record4[y])
                else:
                    sum_record34[sum34] = len(record3[x]) * len(record4[y])
        sum = 0
        for i in sum_record12.keys():
            j = 0 - i
            if j in sum_record34.keys():
                sum += (sum_record12[i] * sum_record34[j])
        return sum

2.3 阅读材料改进

思路一致。但是会在自己的代码上将最后一次遍历结合到上面的操作中。

class Solution(object):
    def fourSumCount(self, nums1, nums2, nums3, nums4):
        hashmap = dict()
        for n1 in nums1:
            for n2 in nums2:
                if n1 + n2 in hashmap:
                    hashmap[n1+n2] += 1
                else:
                    hashmap[n1+n2] = 1
        count = 0
        for n3 in nums3:
            for n4 in nums4:
                key = - n3 - n4
                if key in hashmap:
                    count += hashmap[key]
        return count

三、赎金信

3.1 题目:383. 赎金信

3.2 解题过程

class Solution(object):
    def canConstruct(self, ransomNote, magazine):
        """
        :type ransomNote: str
        :type magazine: str
        :rtype: bool
        """
        if len(ransomNote) > len(magazine):
            return False
        hashmagzine = {}
        for i in magazine:
            if i in hashmagzine.keys():
                hashmagzine[i] += 1
            else:
                hashmagzine[i] = 1
        for i in ransomNote:
            if i in hashmagzine.keys() and hashmagzine[i] > 0:
                hashmagzine[i] -= 1
            else:
                return False
        return True

3.3 阅读材料改进

思路差不多,但是更加推荐用数组完成。因为数组不需要进行底层的维护。

四、三数之和

4.1 题目:15. 三数之和

4.2 解题过程

要满足的条件数不可重复利用,且元组不重复。

首先是暴力解决,不出意外超时。

class Solution(object):
    def threeSum(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        relist = []
        for i in range(len(nums)):
            for j in range(i, len(nums)):
                for k in range(len(nums)):
                    if i != j and j != k and i != k:
                        sum = nums[i]+nums[j]+nums[k]
                        if sum == 0:
                            r = [nums[i], nums[j], nums[k]]
                            r.sort()
                            if r not in relist:
                                relist.append(r)
        return relist

思考更加快速的方法。随想录提示用双指针法。三个数如何双指针,先算一个再算一个吗?

实在没有写出来,看随想录解答。

4.3 阅读材料改进

随想录的思路很巧妙,设置双指针+循环的方法!其中去重也很重要!

class Solution(object):
    def threeSum(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        rlist = []
        nums.sort()
        if len(nums) < 3:
            return rlist
        for i in range(len(nums)-2):
            cur = nums[i]
            left = i+1
            right = len(nums)-1
            if nums[i] > 0:
                break
            if i >= 1 and nums[i] == nums[i-1]:
                continue
            while left < right:
                if cur + nums[left] + nums[right] > 0:
                    right -= 1
                elif cur + nums[left] + nums[right] < 0:
                    left += 1
                elif cur + nums[left] + nums[right] == 0:
                    rlist.append([cur, nums[left], nums[right]])
                    while left < right and nums[right-1]==nums[right]:
                        right -= 1
                    while left < right and nums[left+1] == nums[left]:
                        left += 1
                    right -= 1
                    left += 1
        return rlist

五、1. 四数之和

5.1 题目:18. 四数之和

5.2 解题过程

这一眼就能看出和上一题有很相似,但是要利用上一题的思路感觉难度还是很大。最主要还是不同元素,又不能重复。思路还是打不开。看随想录

5.3 阅读材料改进

以下是复现代码:

class Solution(object):
    def fourSum(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[List[int]]
        """
        rlist = []
        nums.sort()
        if len(nums) < 4:
            return rlist
        for k in range(len(nums)):
            if k>0 and nums[k] == nums[k-1]:
                continue
            for i in range(k+1, len(nums)):
                cur = nums[i]
                left = i + 1
                right = len(nums) - 1
                if i > k+1 and nums[i] == nums[i - 1]:
                    continue
                while left < right:
                    if nums[k]+cur + nums[left] + nums[right] > target:
                        right -= 1
                    elif nums[k]+cur + nums[left] + nums[right] < target:
                        left += 1
                    elif nums[k]+cur + nums[left] + nums[right] == target:
                        rlist.append([nums[k], cur, nums[left], nums[right]])
                        while left < right and nums[right - 1] == nums[right]:
                            right -= 1
                        while left < right and nums[left + 1] == nums[left]:
                            left += 1
                        right -= 1
                        left += 1
        return rlist
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值