代码随想录算法训练营第七天 | 454.四数相加 383.赎金信 15.三数之和 18.四数之和

454.四数相加

题目:给你四个整数数组 nums1、nums2、nums3 和 nums4 ,数组长度都是 n ,请你计算有多少个元组 (i, j, k, l) 能满足:
0 <= i, j, k, l < n
nums1[i] + nums2[j] + nums3[k] + nums4[l] == 0

解题:
思路:使用map,key为a+b,value为出现次数。再遍历k、l寻找0-a-b。
关键:

  1. 遍历1、2数组并记录record时,区分次数+1还是=1;
  2. 遍历3、4数组时,找到对应的key来统计对应的value,是相加而不是相乘!!两个哈希才相乘
    报错:for i in nums1:而不是range(len(nums1)),遍历数值而不是下标。
点击查看代码
class Solution:
    def fourSumCount(self, nums1: List[int], nums2: List[int], nums3: List[int], nums4: List[int]) -> int:
        record={}
        count=0
        for i in nums1:
            for j in nums2:
                if i+j in record:
                    record[i+j]+=1
                else:
                    record[i+j]=1
        for k in nums3:
            for l in nums4:
                if 0-k-l in record:
                    count+=record[0-k-l]
        return count

383.赎金信

题目:给你两个字符串:ransomNote 和 magazine ,判断 ransomNote 能不能由 magazine 里面的字符构成。
如果可以,返回 true ;否则返回 false 。
magazine 中的每个字符只能在 ransomNote 中使用一次。

解题:

思路:和242.有效的字母异位词很像,我就学习了那个的写法,区别就是242要全=0才满足题意,这儿只要不小于0就可以了。一个哈希表就够用了~

一、

点击查看代码
class Solution:
    def canConstruct(self, ransomNote: str, magazine: str) -> bool:
        record_m=[0]*26
        for i in magazine:
            record_m[ord(i)-ord('a')]+=1
        for j in ransomNote:
            record_m[ord(j)-ord('a')]-=1
        for k in range(26):
            if record_m[k]<0:
                return False
        return True

二、用count()数每个字符出现的次数,记得set(ransomNote)转化成哈希表,这个能打败99.79%!

点击查看代码
class Solution:
    def canConstruct(self, ransomNote: str, magazine: str) -> bool:
        return all(ransomNote.count(c) <= magazine.count(c) for c in set(ransomNote))

15.三数之和

题目:给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != j、i != k 且 j != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请
你返回所有和为 0 且不重复的三元组。
注意:答案中不可以包含重复的三元组。

解题:

思路:哈希表解决去重太费时难考虑全,且是在一个数组里找三元组,适合双指针。
遍历i,同时定义left=i+1,right=len(nums)-1,通过比较三个数之和,>0,right左移,<0,left右移。

关键:

  1. 对a去重,判断nums[i]与nums[i-1]是否相同,因为三元组内的元素是可重复的;
  2. 对b、c去重,应该放在找到一个三元组后,sum=0部分

报错:

  1. 用elif不是if,避免错误分支进入;
  2. if i > 0 and...:和while right > left and...:都不能落下这个一个条件,避免越界访问nums[i-1]即nums[-1]
点击查看代码
class Solution:
    def threeSum(self, nums: List[int]) -> List[List[int]]:
        result=[]
        nums.sort()
        for i in range(len(nums)):
            if nums[i]>0: #剪枝
                return result
            if i>0 and nums[i]==nums[i-1]: #去重
                continue
            left=i+1
            right=len(nums)-1
            while right>left:
                sum=nums[i]+nums[left]+nums[right]
                if sum<0:
                    left+=1
                elif sum>0:
                    right-=1
                else:
                    result.append([nums[i],nums[left],nums[right]])
                    while right>left and nums[right]==nums[right-1]:right-=1 #去重
                    while right>left and nums[left]==nums[left+1]:left+=1
                    left+=1
                    right-=1
        return result

18.四数之和

题目:给你一个由 n 个整数组成的数组 nums ,和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]] (若两个四元组元素一一对应,则认为两个四元组重复):
0 <= a, b, c, d < n
a、b、c 和 d 互不相同
nums[a] + nums[b] + nums[c] + nums[d] == target
你可以按 任意顺序 返回答案 。

解题:

思路:三数之和之外再加一层遍历。剪枝懒得看了不用也能过。

点击查看代码
class Solution:
    def fourSum(self, nums: List[int], target: int) -> List[List[int]]:
        result=[]
        nums.sort()
        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=j+1
                right=len(nums)-1
                while right>left:
                    sum=nums[i]+nums[j]+nums[left]+nums[right]
                    if sum<target:
                        left+=1
                    elif sum>target:
                        right-=1
                    else:
                        result.append([nums[i],nums[j],nums[left],nums[right]])
                        while right>left and nums[right]==nums[right-1]:right-=1
                        while right>left and nums[left]==nums[left+1]:left+=1
                        left+=1
                        right-=1
        return result

心得:

IndentationError: unindent does not match any outer indentation level 缩进问题
SyntaxError: 'return' outside function 缩进空格问题

posted @ 2024-06-11 10:53  Y荷兰豆Y  阅读(3)  评论(0编辑  收藏  举报