LeetCode 18.四数之和

题目:


给定一个包含 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]
]

思路:

看到这个题目瞬间想到了上题目中三数之和的双指针移动方法,大就左移,小右移。

  • 首先sort排序是必须要的,它会让你遍历出符合条件相同元素的情况。
  • 去除重复元素,这里有2种方法,一种是用set函数直接去重最后再取出,第二种是通过count来判断并remove 。

方法一:

import copy
class Solution(object):
    def fourSum(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[List[int]]
        """
        nums.sort()
        ans=set()
        #res = []
        
        for i in range(len(nums)-3):
            for j in range(i+1,len(nums)-2):
                left=j+1#左指针
                right=len(nums)-1#右指针
                while(right>left):
                    temp=nums[i]+nums[j]+nums[left]+nums[right]
                    if temp==target:
                        #res.append([nums[i],nums[j],nums[left],nums[right]])
                        ans.add((nums[i],nums[j],nums[left],nums[right]))
                        left+=1
                        right-=1
                    if temp>target:
                        right-=1#右指针左移
                    if temp<target:
                        left+=1#反之
        #取出set中元素赋值到list中。               
        rec=[]
        #方法一
        for i in ans:
            rec.append(list(i))
        return rec
      	#方法二
        #print 'res',res
        #list_arr = copy.copy(res)
        #for k,v in enumerate(list_arr): #删除重复元素
        #    while res.count(v) >=2:
        #        res.remove(v)
       	#print 'temp_list After = ',res
        #return res

时间有点感人:

执行用时 :824 ms, 在所有 Python 提交中击败了28.22%的用户

内存消耗 :12.7 MB, 在所有 Python 提交中击败了14.29%的用户

方法二:

这个方法也很巧妙,通过字典记录所有四数拆成两两之和的位置情况,看code理解逻辑吧。

import collections
class Solution(object):
    def fourSum(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[List[int]]
        """
        n,res=len(nums),[]
        d=collections.defaultdict(list)
        nums.sort()

        for i in range(n):
            for j in range(i+1,n):
                s=nums[i]+nums[j]
                if target-s in d:
                    for a,b in d[target-s]:
                        if b<i and ([nums[a],nums[b],nums[i],nums[j]]) not in res:
                            res.append([nums[a],nums[b],nums[i],nums[j]])
                d[s].append([i,j])
        return res

执行用时 :112 ms, 在所有 Python 提交中击败了73.59%的用户

内存消耗 :18.2 MB, 在所有 Python 提交中击败了14.29%的用户

原文地址:https://www.cnblogs.com/xiaoqiangink/p/13152237.html