csdn_spider/blog/ds19991999/原创-- leetcode15-三数之和.md

4.2 KiB
Raw Blame History

原创

leetcode15-三数之和

leetcode15-三数之和

题目详见:https://leetcode-cn.com/problems/3sum/description/

给定一个包含 n 个整数的数组 nums判断 nums 中是否存在三个元素 abc ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。

注意:答案中不可以包含重复的三元组。

例如, 给定数组 nums = [-1, 0, 1, 2, -1, -4]

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

这道题我遇到好几次了B站后台开发工程师笔试题就考了这个。今天就来总结一下解决方案。
这道题并不难,正常人的第一反应肯定是三个循环,再简单不过了,可是时间复杂度是不是有点大。。。提交也不让通过是吧。
首先写好边界条件,数组小于三个元素就不满足条件:

result = []
nums_len = len(nums)
if nums_len < 3:
	return result

注意我们用的是Python语言所以可以直接先用内建函数sort()排序方便操作。然后可以用一个for循环两个指针遍历,时间复杂度也就是

    o
   
   
    (
   
   
    
     n
    
    
     2
    
   
   
    )
   
  
  
   o(n^2)
  
 
o(n2),与之前的三循环减小了不少。了解了这些差不多就可以实现代码了。
class Solution(object):
    def threeSum(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        result = list()
        nums_len = len(nums)
        if nums_len < 3:
            return result
        l, r, dif = 0, 0, 0
        nums.sort()
        for i in range(nums_len - 2):
            if nums[i] > 0: 
                break
            if i > 0 and nums[i - 1] == nums[i]:
                continue

            l = i + 1
            r = nums_len - 1
            dif = -nums[i]
            while l < r:
                if nums[l] + nums[r] == dif:
                    result.append([nums[l], nums[r], nums[i]])
                    # 这两个while完全可以不要
                    while l < r and nums[l] == nums[l + 1]:
                        l += 1
                    while l < r and nums[r] == nums[r - 1]:
                        r -= 1
                    l += 1
                    r -= 1
                elif nums[l] + nums[r] < dif:
                    l += 1
                else:
                    r -= 1
        
        return result

另外leetcode16题也是差不多这个意思

例如,给定数组 nums = [-121-4], 和 target = 1.与 target 最接近的三个数的和为 2. (-1 + 2 + 1 = 2).

思路一模一样一个for加上两个指针时间复杂度为

    O
   
   
    (
   
   
    
     n
    
    
     2
    
   
   
    )
   
  
  
   O(n^2)
  
 
O(n2)
class Solution(object):
    def threeSumClosest(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: int
        """
#         n = len(nums)
#         if n<3:return None
#         res = sum(nums[0:3])
#         diff = abs(res - target)
        
#         for i in range(0,n-2):
#             for j in range(i+1,n-1):
#                 for k in range(j+1,n):
#                     tmp = nums[i]+nums[j]+nums[k]
#                     if diff > abs(tmp - target):
#                         diff = abs(tmp - target)
#                         res = tmp
#         return res               
        n = len(nums)
        if n<3:return None
        nums.sort()
        res = sum(nums[0:3])
        diff = abs(res - target)
        
        for i in xrange(len(nums)-2):
            low = i+1
            high = len(nums)-1
            while low<high:
                tmp = nums[i]+nums[low]+nums[high]
                if abs(res-target) > abs(tmp-target):res = tmp
                elif target < tmp: high -= 1
                else: low += 1
        return res