• [leetcode]4Sum @ Python


    原题地址:http://oj.leetcode.com/problems/4sum/

    题意:从数组中找到4个数,使它们的和为target。要求去重,可能有多组解,需要都找出来。

    解题思路:一开始想要像3Sum那样去解题,时间复杂度为O(N^3),可无论怎么写都是Time Limited Exceeded。而同样的算法使用C++是可以通过的。说明Python的执行速度比C++慢很多。还说明了一点,大概出题人的意思不是要让我们去像3Sum那样去解题,否则这道题就出的没有意义了。这里参考了kitt的解法:http://chaoren.is-programmer.com/posts/45308.html

           需要用到哈希表的思路,这样可以空间换时间,以增加空间复杂度的代价来降低时间复杂度。首先建立一个字典dict,字典的key值为数组中每两个元素的和,每个key对应的value为这两个元素的下标组成的元组,元组不一定是唯一的。如对于num=[1,2,3,2]来说,dict={3:[(0,1),(0,3)], 4:[(0,2),(1,3)], 5:[(1,2),(2,3)]}。这样就可以检查target-key这个值在不在dict的key值中,如果target-key在dict中并且下标符合要求,那么就找到了这样的一组解。由于需要去重,这里选用set()类型的数据结构,即无序无重复元素集。最后将每个找出来的解(set()类型)转换成list类型输出即可。

    代码:

    class Solution:
        # @return a list of lists of length 4, [[val1,val2,val3,val4]]
        def fourSum(self, num, target):
            numLen, res, dict = len(num), set(), {}
            if numLen < 4: return []
            num.sort()
            for p in range(numLen):
                for q in range(p+1, numLen): 
                    if num[p]+num[q] not in dict:
                        dict[num[p]+num[q]] = [(p,q)]
                    else:
                        dict[num[p]+num[q]].append((p,q))
            for i in range(numLen):
                for j in range(i+1, numLen-2):
                    T = target-num[i]-num[j]
                    if T in dict:
                        for k in dict[T]:
                            if k[0] > j: res.add((num[i],num[j],num[k[0]],num[k[1]]))
            return [list(i) for i in res]

    再贴两个过不了的O(N^3)写法。

    一:

    class Solution:
        # @return a list of lists of length 4, [[val1,val2,val3,val4]]
        def fourSum(self, num, target):
            num.sort(); res=[]
            for i in range(len(num)):
                if i>0 and num[i]==num[i-1]: continue
                for j in range(i+1,len(num)):
                    if j>i+1 and num[j]==num[j-1]: continue
                    l=j+1; r=len(num)-1
                    while l<r:
                        sum=num[i]+num[j]+num[l]+num[r]
                        if sum>target:
                            r-=1
                        elif sum<target:
                            l+=1
                        elif l>j+1 and num[l]==num[l-1]:
                            l+=1
                        elif r<len(num)-1 and num[r]==num[r+1]:
                            r-=1
                        else:
                            res.append([num[i],num[j],num[l],num[r]])
                            l+=1; r-=1
            return res

    二:

    class Solution:
        # @return a list of lists of length 4, [[val1,val2,val3,val4]]
        def fourSum(self, num, target):
            num.sort(); res=[]
            for i in range(len(num)-3):
                if i==0 or num[i]>num[i-1]:
                    for j in range(i+1,len(num)-2):
                        if j==i+1 or num[j]>num[j-1]:
                            left=j+1; right=len(num)-1
                            while left<right:
                                if num[i]+num[j]+num[left]+num[right]==target:
                                    res.append([num[i],num[j],num[left],num[right]])
                                    left+=1; right-=1
                                    while left<right and num[left]==num[left-1]: left+=1
                                    while left<right and num[right]==num[right+1]: right-=1
                                elif num[i]+num[j]+num[left]+num[right]>target:
                                    while left<right:
                                        right-=1
                                        if num[right]<num[right+1]: break
                                else:
                                    while left<right:
                                        left+=1
                                        if num[left]>num[left-1]: break
            return res
  • 相关阅读:
    A05. openstack架构实战-nova服务控制节点安装
    A04. openstack架构实战-glance服务安装
    A03. openstack架构实战-keystone安装
    SSH暴力破解的解读与防御
    tcpdump抓包命令使用
    Superspeed.sh 一键测试服务器到中国上传/下载速度
    Windows ping TCP端口工具之tcping
    实验验证centos 7 系统不会缓存dns信息
    Linux下的TCP测试工具——TCPING安装简明教程
    Debian 9.12 live系统密码重置
  • 原文地址:https://www.cnblogs.com/zuoyuan/p/3699384.html
Copyright © 2020-2023  润新知