leetcode | 数组 | 两数之和 | 三数之和 | 最近的三数之和 | 四数之和

1. 两数之和

  1. 暴力解法
class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:
        for i in range(len(nums)):
            for j in range(i+1,len(nums)):
                if nums[i] + nums[j] == target:
                    return [i, j]
  1. 判断target - num[i]是否在nums中并且不是num[i], 不是就用index()函数找到其位置
class Solution(object):
    def twoSum(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[int]
        """

        for i in range(len(nums)):
            if (target-nums[i]) in nums:
                j = nums.index(target-nums[i])
                if i!=j:
                    return [i, j]
                else:
                    continue
  1. 在num[i]之前定位j
class Solution(object):
    def twoSum(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[int]
        """
        j = -1
        for i in range(1,len(nums)):
            temp_nums = nums[:i]
            if (target-nums[i]) in temp_nums:
                j = temp_nums.index(target-nums[i])
                break
        if j>=0:
            return [i, j]
  1. 在num[i]之后定位,效果不如解法3
class Solution(object):
    def twoSum(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[int]
        """
        j = -1
        for i in range(0,len(nums)-1):
            temp_nums = nums[i+1:]
            if (target-nums[i]) in temp_nums:
                j = temp_nums.index(target-nums[i]) + i + 1
                break
        if j>=0:
            return [i, j]
  1. 在hash的num之前进行查找,为什么会有人想到这么机智的办法
class Solution(object):
    def twoSum(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[int]
        """
        # hash dict
        hash = {}
        # 仅在num[i]之前的dict中查找
        for i,num in enumerate(nums):
            if hash.get(target - num) is not None:
                return [i, hash.get(target-num)]
            hash[num] = i

15. 三数之和

class Solution(object):
    def threeSum(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        # 固定K位置,移动ij
        ans = []
        nums.sort()
        for k in range(len(nums)-2):
            i, j = k+1, len(nums) - 1 # i,j的初始位置是k后片段的两个极端点
            if nums[k] > 0: break
            if k > 0 and nums[k] == nums[k-1] : continue # 跳过重复的K
            while i < j: # i不断前移,j不断后移,直到相遇跳出循环, i!=j 不对

                s = nums[i] + nums[j] + nums[k]
                if s > 0:
                    j -= 1
                    while i < j and nums[j] == nums[j+1]: j -= 1 # 在i<j的前提下,不断往左倒退直到和现在的j不相等为止

                elif s < 0:
                    i += 1
                    while i < j and nums[i] == nums[i-1]: i += 1 # 在i<j的前提下,不断往右前进直到和现在的i不相等为止

                else:
                    ans.append([nums[k], nums[i], nums[j]])
                    # i j 还需要继续走 可能有其他i j 组合和k=0
                    i += 1
                    while i < j and nums[i] == nums[i - 1]: i += 1  # 在i<j的前提下,不断往右前进直到和现在的i不相等为止
                    j -= 1
                    while i < j and nums[j] == nums[j + 1]: j -= 1  # 在i<j的前提下,不断往左倒退直到和现在的j不相等为止
        return ans

16. 最接近的三数之和

定义一个最小差值,每次计算出一个差值后和最小差值的绝对值比较,取更小的差值,如果差值=0直接return target,否则return最小差值和target的和

class Solution(object):
    def threeSumClosest(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: int
        """
        nums.sort()
        # 设置一个最接近和和次接近和,i,j朝着更接近target的方向走
        mincha = nums[0] + nums[1] + nums[2] - target
        for k in range(len(nums) - 2):
            i, j = k + 1, len(nums) - 1
            if k > 0 and nums[k] == nums[k - 1]: continue
            while i < j:
                cha = nums[i] + nums[j] + nums[k] - target
                # cha < 0 增加i cha > 0 减小j cha = 0 break
                if cha < 0:
                    i += 1
                    while i < j and nums[i-1] == nums[i] : i += 1
                elif cha > 0:
                    j -= 1
                    while i < j and nums[j+1] == nums[j] : j -= 1
                else:
                    return target
                if abs(cha) < abs(mincha):
                    mincha = cha
        return mincha + target

在这里插入图片描述
可以说是贼开心了!

18. 四数之和

和三数之和的区别是需要用双循环固定前两个数,以及这道题可以有重复元素出现,所以不需要while跳重复数字,set()可以add()进一个元组,

class Solution(object):
    def fourSum(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[List[int]]
        """
        nums.sort()
        n = len(nums)
        ans = set()
        # 固定前两个数,后两个数一左一右地移动
        for i in range(0, n-3):
            for j in range(i+1, n-2):
                k, l = j + 1, n - 1
                while k < l:
                    temp = nums[i] + nums[j] + nums[k] + nums[l]
                    if temp < target:
                        k += 1
                    elif temp > target:
                        l -= 1
                    else:
                        ans.add((nums[i], nums[j], nums[k], nums[l])) # set() .add()可以添加一个元组
                        k += 1
                        l -= 1
        res = []
        for a in ans:
            res.append(list(a))
        return res

454. 四数相加II

Counter()是计算可迭代对象每种元素出现的个数

class Solution(object):
    def fourSumCount(self, A, B, C, D):
        """
        :type A: List[int]
        :type B: List[int]
        :type C: List[int]
        :type D: List[int]
        :rtype: int
        """
        # 先计算a+b的和的字典
        from collections import Counter 
        dict = Counter(a+b for a in A for b in B)
        # 在字典中找-c-d的值,有多少个说明有多少个配对的四元组
        return sum(dict.get(-c-d, 0) for c in C for d in D)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值