DAY 7 454. 4Sum II 383. Ransom Note 15. 3Sum 18. 4Sum

454. 4Sum II

Using brutal force, we can do 4 iterations for each of the nums and count all the pairs giving a sum of 0. However, a better way to reduce the time complexity from N^4 to N^2 is, to log all the pairs of adding sum from nums 1 and nums 2. Then iterate through nums 3 and 4 and check if 0 - (nums 3 + nums 4) exists in the table. If so, add up the number of occurrences. Time complexity = N(n^4)

class Solution:
    def fourSumCount(self, nums1: List[int], nums2: List[int], nums3: List[int], nums4: List[int]) -> int:
        length = len(nums1)
        result = dict()
        count = 0
        for i in range(length):
            for j in range(length):
                key = nums1[i] + nums2[j]

                if key not in result.keys():
                    result[key] = 1
                else:
                    result[key] += 1
        
        for i in range(length):
            for j in range(length):
                key =  0 - (nums3[i] + nums4[j])
                if key in result.keys():

                    count += result[key]

        return count

383. Ransom Note

We can use either dict (map) or array to solve this problem. array mighrt be better because 26 letters are finite and an array will save some time in operations. so we convert the letters of magazine to a table to mark the occurrence. then we subtract all the occurrences from ransomNote. if a letter is not marked, then False. Else, it must be True. Time complexity should be N(n)

class Solution:
    def canConstruct(self, ransomNote: str, magazine: str) -> bool:

        count_table = [0]*26

        for i in magazine:
            count_table[ord(i) - ord('a')] += 1


        for i in ransomNote:
            if count_table[ord(i) - ord('a')] == 0:
                return False
            else:
                count_table[ord(i) - ord('a')] -= 1

        return True 

15. 3Sum

0. sort the array

1. fix a and then use two pointers to find sum == 0 from front and back

2. remove duplicates from a,b,and c. the adjacent next value cannot be the same

Attention: 

i,left,right are index not value.

To remove duplicates from a, nums[a] != nums[a-1] (a>0) so at least we can log a value before we move on. Nonetheless, for b and c, nums[b= != nums[b+1] we can skip the next value because we already logged the previous value. Time complexity N(n^2)

class Solution:
    def threeSum(self, nums: List[int]) -> List[List[int]]:
        ans = []
        nums.sort()
        print(nums)

        for i in range(len(nums)):
            left = i+1
            right = len(nums) - 1

            if i > 0 and nums[i] == nums[i-1]:  # remove duplicate from a
                continue

            while(left < right):
                total = nums[i] + nums[left] + nums[right]
                if total < 0:
                    left = left + 1
                elif total > 0:
                    right = right - 1
                else:
                    ans.append([nums[i],nums[left],nums[right]])
                    while left < right and nums[left] == nums[left+1]: left = left + 1 # remove duplicates from b
                    while left < right and nums[right] == nums[right-1]: right = right - 1 # remove duplicates from c
                    left = left + 1
                    right = right - 1
        
        return ans

18. 4Sum 

add one more layer out of 3sum. the second iterator should ski[p when j > i+1, because we want to skip the first index for every i loop.

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

        for i in range(n):
            if i > 0 and nums[i] == nums[i-1]:
                continue
            for j in range(i+1, n):
                if j > i + 1 and nums[j] == nums[j-1]:
                    continue
                left = j + 1
                right = n - 1

                while left < right:
                    total = nums[i] + nums[j] + nums[left] + nums[right]

                    if total > target:
                        right -= 1
                    elif total < target:
                        left += 1
                    else:
                        res.append([nums[i],  nums[j], nums[left], nums[right]])
                        while left < right and nums[left] == nums[left + 1]: left += 1
                        while left < right and nums[right] == nums[right - 1]: right -= 1
                        left += 1
                        right -= 1
        return res

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值