代码随想录算法训练营第7天 | 哈希表 | ● 454.四数相加II ● 383. 赎金信 ● 15. 三数之和 ● 18. 四数之和 ● 总结

454. 4Sum II

Given four integer arrays nums1, nums2, nums3, and nums4 all of length n, return the number of tuples (i, j, k, l) such that:
0 <= i, j, k, l < n
nums1[i] + nums2[j] + nums3[k] + nums4[l] == 0

Sol:

class Solution:
    def fourSumCount(self, nums1: List[int], nums2: List[int], nums3: List[int], nums4: List[int]) -> int:
        hash_map={}
        res=0
        for x in nums1:
            for y in nums2:
                hash_map[x+y]=hash_map.get(x+y,0)+1 
        
        for x in nums3:
            for y in nums4:
                test = 0-x-y
                if test in hash_map:
                    res+=hash_map[test]
        return res
  • Note: 两两组合,变成Two Sum
  • O ( n 2 ) , O ( n 2 ) O(n^2), O(n^2) O(n2),O(n2)

================================================

383. Ransom Note

Given two strings ransomNote and magazine, return true if ransomNote can be constructed by using the letters from magazine and false otherwise.
Each letter in magazine can only be used once in ransomNote.

Example 1:
Input: ransomNote = “a”, magazine = “b”
Output: false
Example 2:
Input: ransomNote = “aa”, magazine = “aab”
Output: true

Sol:

class Solution:
    def canConstruct(self, ransomNote: str, magazine: str) -> bool:
        tab = {}
        for x in magazine:
            tab[x]=tab.get(x,0)+1
        for x in ransomNote:
            if x not in tab or tab[x]==0:
                return False
            else:
                tab[x]-=1
        return True

================================================

15. 3Sum

Given an integer array nums, return all the triplets [nums[i], nums[j], nums[k]] such that i != j, i != k, and j != k, and nums[i] + nums[j] + nums[k] == 0.
Notice that the solution set must not contain duplicate triplets.
Example 1:
Input: nums = [-1,0,1,2,-1,-4]
Output: [[-1,-1,2],[-1,0,1]]
Explanation:
nums[0] + nums[1] + nums[2] = (-1) + 0 + 1 = 0.
nums[1] + nums[2] + nums[4] = 0 + 1 + (-1) = 0.
nums[0] + nums[3] + nums[4] = (-1) + 2 + (-1) = 0.
The distinct triplets are [-1,0,1] and [-1,-1,2].
Notice that the order of the output and the order of the triplets does not matter.

Sol:

class Solution:
    def threeSum(self, nums: List[int]) -> List[List[int]]:
        nums=sorted(nums)#sort first
        res=[]
        #双指针法
        #i,left,right:results x,y,z
        for i in range(len(nums)):
            if nums[i]>0: #if first >0, no need to check later larger values
                return res
            if i>0 and nums[i] == nums[i-1]: #去重,和前一个比
                continue   
            left, right = i+1, len(nums)-1
            while left<right:
                sum3 = nums[i]+nums[left]+nums[right]
                if sum3 == 0:
                    res.append([nums[i], nums[left], nums[right]])
                    while left<right and nums[right]==nums[right-1]: #去重
                        right-=1
                    while left<right and nums[left]==nums[left+1]: #去重
                        left+=1
                    right-=1 #记得要走一步:当前值是重复数的最后一个,要走到下一个新数
                    left+=1
                elif sum3>0: #大了,right移动
                    right-=1
                elif sum3<0: #小了,left移动
                    left+=1
        return res

  • Note: 哈希法可做但是复杂,双指针法方便
  • O ( n 2 ) , O ( 1 ) O(n^2), O(1) O(n2),O(1)

================================================

18. 4Sum

Given an array nums of n integers, return an array of all the unique quadruplets [nums[a], nums[b], nums[c], nums[d]] such that:
0 <= a, b, c, d < n
a, b, c, and d are distinct.
nums[a] + nums[b] + nums[c] + nums[d] == target
You may return the answer in any order.

Sol

class Solution:
    def fourSum(self, nums: List[int], target: int) -> List[List[int]]:
        nums.sort()
        res = []

        for i in range(len(nums)):
            if i>0 and nums[i]==nums[i-1]:
                continue
            for j in range(i+1,len(nums)):
                if j>i+1 and nums[j]==nums[j-1]:
                    continue
                left,right=j+1,len(nums)-1
                while left<right:
                    sum4=nums[i]+nums[j]+nums[left]+nums[right]
                    if sum4==target:
                        res.append([nums[i],nums[j],nums[left],nums[right]])
                        while left<right and nums[right] == nums[right-1]:
                            right-=1
                        while left<right and nums[left] == nums[left+1]:
                            left+=1
                        right-=1
                        left+=1
                    elif sum4>target:
                        right-=1
                    elif sum4<target:
                        left+=1
        return res
  • Note: similar to 3Sum, only fix i,j two loops and remove duplicates for both loops.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值