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

454.四数相加II

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
        """
        
        result=dict()
        
        count = 0
        for i1 in range(len(nums1)):
            for i2 in range(len(nums2)):
                if nums1[i1] + nums2[i2] not in result.keys():
                    result[nums1[i1] + nums2[i2]] = 1
                else:
                    result[nums1[i1] + nums2[i2]] +=1
                
        for i3 in range(len(nums3)):
            for i4 in range(len(nums4)):
                if -1*(nums3[i3] + nums4[i4]) in result.keys():
                    count += result[-1*(nums3[i3] + nums4[i4])]
                
        return count

383.赎金信

  • 题目链接:383.赎金信
  • 遍历赎金信时就可以return false了
class Solution(object):
    def canConstruct(self, ransomNote, magazine):
        """
        :type ransomNote: str
        :type magazine: str
        :rtype: bool
        """
        
        alphabet=[0]*26
        
        for i in magazine:
            alphabet[ord(i)-ord('a')]+=1
        
        for j in ransomNote:
            alphabet[ord(j)-ord('a')]-=1
        
        for k in range(26):
            if alphabet[k]<0:
                return False
        
        return True
  • 使用count的方法
class Solution:
    def canConstruct(self, ransomNote: str, magazine: str) -> bool:
        for char in ransomNote:
            if char in magazine and ransomNote.count(char) <= magazine.count(char):
                continue
            else:
                return False
        return True

15. 三数之和

  • 题目链接:15. 三数之和
  • 先排序
  • 遍历i时注意
    • 如果i已经大于零则可以直接结束
    • 去重问题
  • 和为0时注意
    • 此时还要移动快慢指针
    • 去重问题
class Solution(object):
    def threeSum(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        nums.sort()
        result = []

        for i in range(len(nums)):

            if nums[i] > 0:
                return result
            
            if i > 0 and nums[i] == nums[i - 1]:
                continue

            FastIdx = len(nums)-1
            SlowIdx = i+1

            while FastIdx>SlowIdx:
                if nums[FastIdx]+nums[SlowIdx] < -1*nums[i]:
                    SlowIdx += 1
                elif nums[FastIdx]+nums[SlowIdx] > -1*nums[i]:
                    FastIdx -= 1
                else:
                    result.append([nums[i], nums[SlowIdx], nums[FastIdx]])

                    while FastIdx > SlowIdx and nums[FastIdx] == nums[FastIdx - 1]:
                        FastIdx -= 1
                    while FastIdx > SlowIdx and nums[SlowIdx] == nums[SlowIdx + 1]:
                        SlowIdx += 1
                        
                    FastIdx -= 1
                    SlowIdx += 1
        
        return result

18. 四数之和

class Solution(object):
    def fourSum(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[List[int]]
        """

        result = []
        nums.sort()

        for a in range(len(nums)):
            for b in range(a+1, len(nums)):
                tmp = target - nums[a] - nums[b]

                c = b+1
                d = len(nums)-1
                
                while c<d:
                    if nums[c] + nums[d] < tmp:
                        c += 1
                    elif nums[c] + nums[d] > tmp:
                        d -= 1
                    else:
                        if [nums[a], nums[b], nums[c], nums[d]] not in result:
                            result.append([nums[a], nums[b], nums[c], nums[d]])

                        c+=1
                        d-=1
        
        return result
  • 带去重的版本(剪枝条件太多了,简单了解了一下)
    • 注意一下不可以直接a>target就return 因为后面的数可能小于0
class Solution(object):
    def fourSum(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[List[int]]
        """

        result = []
        nums.sort()

        for a in range(len(nums)):
            if a>0 and nums[a-1]==nums[a]:
                continue
            for b in range(a+1, len(nums)):
                if b>a+1 and nums[b-1]==nums[b]:
                    continue

                tmp = target - nums[a] - nums[b]

                c = b+1
                d = len(nums)-1
                
                while c<d:
                    if nums[c] + nums[d] < tmp:
                        c += 1
                    elif nums[c] + nums[d] > tmp:
                        d -= 1
                    else:
                        result.append([nums[a], nums[b], nums[c], nums[d]])

                        while c<d and nums[c]==nums[c+1]:
                            c += 1
                        while c<d and nums[d]==nums[d-1]:
                            d -= 1

                        c+=1
                        d-=1
        
        return result

总结

  • 一般来说哈希表都是用来快速判断一个元素是否出现集合里
  • 数组作为哈希表
    • 比如只有小写字母的情况
    • 数组的大小是有限的,受到系统栈空间(不是数据结构的栈)的限制。
    • 如果数组空间够大,但哈希值比较少、特别分散、跨度非常大,使用数组就造成空间的极大浪费。
  • set作为哈希表
    • set是一个集合,里面放的元素只能是一个key,而两数之和这道题目,不仅要判断y是否存在而且还要记录y的下标位置,因为要返回x 和 y的下标。此时set 也不能用。
  • map作为哈希表
    • map是一种<key, value>的结构,本题可以用key保存数值,用value在保存数值所在的下标。所以使用map最为合适。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值