leetcode 454.四数相加II

题目

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

解题思路

1、四个数组分成两组,nums1和nums2为一组(A组),nums3和nums4为一组(B组) --两层for循环分别计算出A、B的值
2、原题目转换为A组和B组的元素和为0,和题目1.两数之和类似 --判断0减去B的值是否在A中(判断元素是否出现用哈希法)
3、计算满足A + B = 0 有多少个元祖,即除了求满足条件的值之外,还要统计值的个数 --满足条件的值为key,值的个数为value(哈希法的数据结构使用字典)

实现代码

from typing import List
class Solution:
    def fourSumCount(self, nums1: List[int], nums2: List[int], nums3: List[int], nums4: List[int]) -> int:
        hashmap = dict()    # key存值,value存值出现的次数
        for n1 in nums1:      
            for n2 in nums2:
                a = n1 + n2
                print('a=', a)
                hashmap[a] = hashmap.get(a, 0) + 1  # 在字典中取key为a的值,如果没有返回0,有就+1
                # print(hashmap)
        
        count = 0
        for n3 in nums3:      
            for n4 in nums4:
                b = n3 + n4
                target = 0 - b
                # print('target=', target)

                if target in hashmap:
                    count += hashmap[target]
        return count

        
test = Solution()
nums1 = [1,2]
nums2 = [-2,-1]
nums3 = [-1,2]
nums4 = [0,2]
print(test.fourSumCount(nums1, nums2, nums3, nums4))

leetcode 383. 赎金信

题目

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

解题思路

判断ransomNote中的元素是否都能在magazine中找到 --哈希法
该题目和242.有效字母异位词一样的解法

实现代码

class Solution:
    def canConstruct(self, ransomNote: str, magazine: str) -> bool:
        arr = [0] * 26
        for i in ransomNote:
            arr[ord(i) - ord('a')] += 1
        for i in magazine:
            arr[ord(i) - ord('a')] -= 1

        # for i in range(26):  # ransomNote = 'fihjjjjei', magazine = 'hjibagacbhadfaefdjaeaebgi' 用例执行失败
        #     if arr[i] <= 0:
        #         return True
        #     else:
        #         return False

        # all()函数:判断给定的可迭代参数iterable中的所有元素是否都为TRUE,如果是返回True,否则返回 False。元素除了是0、空、None、False外都算True。         
        return all(arr[i] <= 0 for i in range(26))   # ransomNote = 'fihjjjjei', magazine = 'hjibagacbhadfaefdjaeaebgi' 用例执行成功

test = Solution()
# ransomNote = "aab"
# magazine = "bc"

# ransomNote = 'ab'
# magazine = 'ab'

# ransomNote = "a"
# magazine = "b"

ransomNote = 'fihjjjjei'    # 1个f,2个i,1个h,4个j,1个e
magazine = 'hjibagacbhadfaefdjaeaebgi'  # 2个f,2个i,1个h,2个j,3个e

print(test.canConstruct(ransomNote, magazine))

leetcode 15. 三数之和

题目

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

解题思路

双指针 + 去重
1、双指针法遍历出所有和为0的三元组
(1)对数组进行排序
(2)for循环遍历数组,i从下标为0的位置开始
(3)定义双指针left和right,left位置为i+1,right位置为数组末尾位len(nums)-1
(4)三元组的和s = nums[i] + nums[left] + nums[right]
(5)通过判断三元组的和来移动双指针
如果s>0,三元组和需要变小,right指针向左移动,right -= 1
如果s<0,三元组的和需要变大,left指针向右移动,left += 1
如果s=0,三元组的和为0,得到结果,将nums[i],nums[left],num[right]添加到数组中,然后继续遍历i,left右移,right左移,直到left与right相遇
2、去掉重复的三元组(注意:是三元组不重复,三元组中的元素是可以重复的)
(1)判断nums[i]和它的前一位nums[i-1]是否重复,如果重复说明值已经在三元组中使用过,所以跳过nums[i]和其对应的三元组结果,继续向后找
(2)判断nums[left+1]和它的前一位num[left]是否重复,如果重复,left继续向右移动 left+=1
(3)判断nums[right-1]和它的后一位nums[right]是否重复,如果重复,right继续向左移动 right-=1

实现代码

class Solution:
    def threeSum(self, nums: List[int]) -> List[List[int]]:
        nums.sort()  # 排序
        res = []
        for i in range(len(nums)):
            if nums[i] > 0:  # 排序后如果第一个值都大于0,则直接返回空数组
                return res

            # nums[i]去重
            if i > 0 and nums[i] == nums[i -1]:  # 如果nums[i]和它的前一位nums[i-1]相等,则要跳过nums[i],i继续向右移动
                continue        

            left = i + 1
            right = len(nums) - 1
            
            while left < right:
                s = nums[i] + nums[left] + nums[right] 
                if s < 0:
                    left += 1
                elif s > 0:
                    right -= 1
                else:
                    res.append([nums[i], nums[left], nums[right]])

                    # nums[right]去重
                    while right > left and nums[right] == nums[right-1]:
                        right -= 1
                    # nums[left]去重 
                    while right > left and nums[left] == nums[left+1]:
                        left += 1
                    
                    right -= 1
                    left += 1
        return res
test = Solution()
nums = [-1,0,1,2,-1,-4]
print(test.threeSum(nums))

leetcode 18. 四数之和

题目

18. 四数之和

解题思路

实现代码


posted on 2024-04-13 22:13  小鹿BAMBI  阅读(1)  评论(0编辑  收藏  举报