代码随想录算法训练营第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.

你可能感兴趣的:(算法,散列表,哈希算法)