【LeetCode 中等题】11-四数之和

声明:

今天是中等题第11道题。给定一个包含 n 个整数的数组 nums 和一个目标值 target,判断 nums 中是否存在四个元素 a,b,c 和 d ,使得 a + b + c + d 的值与 target 相等?找出所有满足条件且不重复的四元组。以下所有代码经过楼主验证都能在LeetCode上执行成功,代码也是借鉴别人的,在文末会附上参考的博客链接,如果侵犯了博主的相关权益,请联系我删除

(手动比心ღ( ´・ᴗ・` ))

正文

题目:给定一个包含 n 个整数的数组 nums 和一个目标值 target,判断 nums 中是否存在四个元素 a,b,c 和 d ,使得 a + b + c + d 的值与 target 相等?找出所有满足条件且不重复的四元组。

注意:

答案中不可以包含重复的四元组。

示例:

给定数组 nums = [1, 0, -1, 0, -2, 2],和 target = 0。

满足要求的四元组集合为:
[
  [-1,  0, 0, 1],
  [-2, -1, 1, 2],
  [-2,  0, 0, 2]
]

解法1。和3数之和的思路很像,就是固定前2个作为i、j遍历,后两个作为p、q双指针逐渐向中间靠拢,以后遇到K数之和的问题都可以套用此范式,前K-2个用K-2个for循环遍历,后面2个用双指针,其中可以做适当剪枝,就是比如说最大和都比target小或者下一个元素值和当前的相等,那么continue,如果最小和大于target直接break,代码如下

执行用时: 104 ms, 在4Sum的Python3提交中击败了98.81% 的用户

class Solution:
    def fourSum(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[List[int]]
        """
        res = []
        n = len(nums)
        nums.sort()    # 这一步千万别漏了
        for i in range(n-3):
            if i>0 and nums[i]==nums[i-1]:continue
            if nums[i]+nums[n-1]+nums[n-2]+nums[n-3] < target:continue    # 最大和都比target小,那么只有增加i,也就是跳过此次循环
            if nums[i]+nums[i+1]+nums[i+2]+nums[i+3] > target:break    # 最小和都比target大,直接break
            for j in range(i+1,n-2):
                if j>0 and nums[j] == nums[j-1]:continue
                if nums[i]+nums[j]+nums[n-1]+nums[n-2]<target:continue
                if nums[i]+nums[j]+nums[j+1]+nums[j+2]>target:break
                l,r = j+1,n-1
                tar = target - nums[i] -nums[j]
                while l < r:
                    if nums[l]+nums[r] == tar:
                        res.append([nums[i],nums[j],nusm[l],nums[r]])
                        l += 1
                        r -= 1
                        while l < r and nums[l] == nums[l-1]:l += 1
                        while l < r and nums[r] == nums[r+1]:r -= 1
                    elif nums[l]+nums[r] > tar:
                        r -= 1
                    else:
                        l += 1
        return res

                    

 解法2。采用递归的方式做,讲真没有细推,其实并不是很理解,代码如下。

执行用时: 112 ms, 在4Sum的Python3提交中击败了97.25% 的用户

class Solution:
    def fourSum(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[List[int]]
        """
        def findNsum(nums, target, N):
            """
            多个数之和这一类问题的通解
            :param nums: 
            :param target: 
            :param N: 
            :return:
            :notes:
                1. 传进来的nums已经完成了从小到大的排序
            """
            res = []
            # early termination
            if len(nums) < N or target < nums[0] * N or target > nums[-1] * N:
                return res

            # two pointer solve sorted 2-sum problem
            if N == 2:
                l, r = 0, len(nums) - 1
                while l < r:
                    s = nums[l] + nums[r]
                    if s < target:
                        l += 1
                    elif s > target:
                        r -= 1
                    else:
                        res.append([nums[l], nums[r]])
                        while l < r and nums[l] == nums[l + 1]:
                            l += 1
                        while l < r and nums[r] == nums[r - 1]:
                            r -= 1
                        l, r = l + 1, r - 1
            else:
                for i, x in enumerate(nums[: -N + 1]):
                    if i == 0 or (i > 0 and nums[i - 1] != x):
                        res1 = findNsum(nums[i + 1: ], target - x, N - 1)
                        if len(res1) > 0:
                            res += [[x] + y for y in res1]
                            
            return res

        return findNsum(sorted(nums), target, 4)

 

结尾

解法1:https://blog.csdn.net/Koala_Tree/article/details/80104382

解法2:LeetCode

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值