代码随想录 day7

# leetcode454.四数相加2

特点:可以重复,不需要去重;四个独立数组

class Solution:
    def fourSumCount(self, nums1: List[int], nums2: List[int], nums3: List[int], nums4: List[int]) -> int:
        dict1 = dict()
        dict2 = dict()
        ans = 0

        for i in nums1:
            for j in nums2:
                dict1[i+j] = dict1.get(i+j, 0)+1

        for i in nums3:
            for j in nums4:
                dict2[i+j] = dict2.get(i+j, 0)+1

        for i in dict1:
            target = -i
            if target in dict2:
                ans += dict1[i] * dict2[target]

        return ans

# leetcode383.赎金信

思路:纯字母,使用list,不需要额外构建hashlist

学习:all()函数的使用,all(条件 for i in range(xx)), 当全部条件成立时,返回True

class Solution:
    def canConstruct(self, ransomNote: str, magazine: str) -> bool:
        # ord()
        list_ransom = [0] * 26
        list_magazine = [0] * 26

        for num in ransomNote:
            list_ransom[ord(num)-ord('a')] += 1

        for num in magazine:
            list_magazine[ord(num)-ord('a')] += 1

        #result = [a - b for a, b in zip(list_magazine, list_ransom)]

        return all(list_magazine[i] >= list_ransom[i] for i in range(26))
        

# leetcode15.三数之和

class Solution: 
    def threeSum(self, nums: List[int]) -> List[List[int]]:
        if not nums or len(nums)<3:
            return []

        results = []
        nums.sort()
        for i in range(len(nums)-2):
            # 如果a大于0,不需要之后的搜索
            if nums[i] > 0:
                return results

            if i==0 or (i>0 and nums[i] != nums[i-1]):
                left = i+1
                right = len(nums)-1
                while left < right:
                    sum_ = nums[i]+nums[left]+nums[right] 
                    if sum_ < 0:
                        left = left+1
                    elif sum_ > 0:
                        right = right-1
                    else:
                        results.append([nums[i],nums[left],nums[right]])
                        # 这里要么动left要么动right,否则死循环
                        # 其实,left right都要动,避免重复
                        # 必须要动到不等于原来的b和c
                        '''
                        while right > left and nums[right] == nums[right - 1]:
                            right -= 1
                        while right > left and nums[left] == nums[left + 1]:
                            left += 1

                        right -= 1
                        left += 1
                        '''
                        # 类do while写法
                        while left<right:
                            right -= 1
                            if nums[right] != nums[right+1]:
                                break

                        while left<right:
                            left += 1
                            if nums[left] != nums[left-1]:
                                break
        return results

# 实现[0,1,1(tar),2,2,2(cur)]将cur移动到tar
# 方法1:
'''
while nums[right] == nums[right-1]: # 这里避免涉及right+1 防止index问题
    right -=1
right -= 1
'''
# 方法2:
# 不行,首先要保证left<right
'''
right -= 1
while nums[right] == nums[right+1]:
    right -= 1
'''
# 方法3:
'''
while True:
    right -= 1
    if nums[right] != nums[right+1]:
        break
'''

思路:使用双指针的思想,限定条件为:去重;优化为:剪枝

# leetcode18.四数之和

和三数之和一样,最重要的思想为:减枝、去重

class Solution:
    def fourSum(self, nums: List[int], target: int) -> List[List[int]]:
        if not nums or len(nums)<4:
            return []
        results = []
        nums.sort()
        for k in range(len(nums)-3):
            if nums[k] > target and target > 0:
                break
            if k>0 and nums[k] == nums[k-1]:
                continue
            for i in range(k+1, len(nums)-2): # 这里k+1容易写错,不是从1开始
                if nums[k]+nums[i] > target and target > 0:
                    break
                # 这里i>k+1容易写错,不是i>1
                if i>k+1 and nums[i] == nums[i-1]:
                    continue
                left = i+1
                right = len(nums) - 1
                while left < right:
                    sum_ = nums[k]+nums[i]+nums[left]+nums[right]
                    if sum_ < target:
                        left = left+1
                    elif sum_ > target:
                        right = right-1
                    else:
                        results.append([nums[k],nums[i],nums[left],nums[right]])
                        while left<right:
                            right -= 1
                            if nums[right] != nums[right+1]:
                                break
                        while left<right:
                            left += 1
                            if nums[left] != nums[left-1]:
                                break
        return results

 容易写错的点是判断i的遍历范围,以及i的去重。

i是从k+1开始的,不是在sum3中从1开始的。别的基本思想相同。

  • 10
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值