zoukankan      html  css  js  c++  java
  • 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%的用户

  • 相关阅读:
    Office转SWF的一些感想(Office2007和Office2010)
    数据库字段为日期类型时
    C#实现office文档转换为PDF格式
    C#.net word excel powerpoint (ppt) 转换成 pdf 文件
    Servlet基础
    Android加速度传感器实现“摇一摇”,带手机振动
    android完全退出应用程序
    【安卓笔记】作为内部类的广播接收者
    Android中使用广播机制退出多个Activity
    [Android] ImageView.ScaleType设置图解
  • 原文地址:https://www.cnblogs.com/xiaoqiangink/p/13152237.html
Copyright © 2011-2022 走看看