leetcode15三数之和、16三数最接近之和、18四数之和总结

这一类的问题相似,只不过是具体个数上有所区别。很自然的一种思路就是暴力破解法,然而这种方法的时间复杂度太高,若为K数之和,时间复杂度可以达到O(nk)。还有一种方法就是采用双指针法,也就是先固定好k-2个数,然后将剩下两个数采用双指针法进行选择。这样前面k-2个位置的选则复杂度为O(nk-2),再算上后面的双指针,总共的时间复杂度也就是O(nk-1),(这时间复杂度也挺高的…)。下面是具体的题目及代码。

  1. 3Sum
    Given an array nums of n integers, are there elements a, b, c in nums such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.

Note:

The solution set must not contain duplicate triplets.

Example:

Given array nums = [-1, 0, 1, 2, -1, -4],

A solution set is:
[
[-1, 0, 1],
[-1, -1, 2]
]
python代码:

def threeSum(self, nums: List[int]) -> List[List[int]]:
        nums.sort()
        ans=[]
        for i in range(len(nums)):
            if nums[i]>0:
                continue
            if i>0 and nums[i]==nums[i-1]:#如果本次循环的值与上次一样就可以直接跳过,下面也是同理。
                continue
            left=i+1
            right=len(nums)-1
            while left<right:
                cur=nums[i]+nums[left]+nums[right]
                if cur==0:
                    ans.append([nums[i],nums[left],nums[right]])
                    left+=1
                    right-=1
                    while nums[left]==nums[left-1] and left<right:
                        left+=1
                    while nums[right]==nums[right+1] and left<right:
                        right-=1
                elif cur>0:
                    right-=1
                    while nums[right]==nums[right+1] and left<right:
                        right-=1
                else:
                    left+=1
                    while nums[left]==nums[left-1] and left<right:
                        left+=1
        return ans

因为题目要求最后的结果不能出现重复,所以我们先进行了排序。注意当满足一些条件的时候,整个的算法可以提前终止或者跳过本次循环。

  1. 3Sum Closest
    Given an array nums of n integers and an integer target, find three integers in nums such that the sum is closest to target. Return the sum of the three integers. You may assume that each input would have exactly one solution.

Example 1:

Input: nums = [-1,2,1,-4], target = 1
Output: 2
Explanation: The sum that is closest to the target is 2. (-1 + 2 + 1 = 2).

Constraints:

3 <= nums.length <= 10^3
-10^3 <= nums[i] <= 10^3
-10^4 <= target <= 10^4

python代码实现

def threeSumClosest(self, nums: List[int], target: int) -> int:
        nums=sorted(nums)
        flag=0
        ans=0
        for i,num_1 in enumerate(nums):
            if i>0 and nums[i]==nums[i-1]:
                continue
            
            j=i+1
            k=len(nums)-1
            while j<k:
                num_2=nums[j]
                num_3=nums[k]
                sum=num_1+num_2+num_3
                if flag==0:
                    flag=1
                    ans=sum
                if abs(sum-target)<abs(ans-target):
                    ans=sum
                if sum==target:
                    return ans #没有最小的
                elif sum<target:
                    j+=1
                    while j>i+1 and nums[j-1]==nums[j] and j<k:
                        j+=1
                else:
                    k-=1
                    while nums[k]==nums[k+1] and j<k:
                        k-=1
        return ans
  1. 4Sum
    Given an array nums of n integers and an integer target, are there elements a, b, c, and d in nums such that a + b + c + d = target? Find all unique quadruplets in the array which gives the sum of target.

Note:

The solution set must not contain duplicate quadruplets.

Example:

Given array nums = [1, 0, -1, 0, -2, 2], and target = 0.

A solution set is:
[
[-1, 0, 0, 1],
[-2, -1, 1, 2],
[-2, 0, 0, 2]
]
代码如下:

 def fourSum(self, nums: List[int], target: int) -> List[List[int]]:
        ans=[]
        nums.sort()
        for i in range(len(nums)-3):
            if i>0 and nums[i]==nums[i-1]:
                continue
            for j in range(i+1,len(nums)-2):
                if j>i+1 and nums[j]==nums[j-1]:
                    continue
                left=j+1
                right=len(nums)-1
                while left<right:
                    cur=nums[i]+nums[j]+nums[left]+nums[right]
                    if cur==target:
                        ans.append([nums[i],nums[j],nums[left],nums[right]])
                        left+=1
                        right-=1
                        while left<right and nums[left]==nums[left-1]:
                            left+=1
                        while left<right and nums[right]==nums[right+1]:
                            right-=1
                    elif cur<target:
                        left+=1
                        while left<right and nums[left]==nums[left-1]:
                            left+=1 
                    else:
                        right-=1
                        while left<right and nums[right]==nums[right+1]:
                            right-=1
        return ans
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值