zoukankan      html  css  js  c++  java
  • LeetCode15:三数之和(双指针)

     解题思路:常规解法很容易想到O(n^3)的解法,但是,n最大为1000,很显然会超时。

    如何优化到O(n^2),a+b+c =0,我们只需要判断 a+b的相反数是否在数组中出现,而且元素的取值范围在1e5的范围内,所以,我们可以空间换时间,开辟一个数组,将第三层的查询O(n)的复杂度降到O(1),需要注意的是,要考虑去重的情况。

    更好的解法:因为常规解法空间消耗有点大,如何降低空间复杂度。

    可以使用双指针,也需要先对nums数组从小到大排好序,在第一层循环中,从0开始遍历,枚举可能的a,然后把a后的区间使用 l ,r 双指针枚举,如果 a + l +r >0,说明 r 应该往左移;a + l+r < 0 ,说明 l 应该往右移;a + l + r =0 ,添加答案,l 往右移并且 r 往左移。

    此外,需要考虑重复的情况,分别设立 pre_a、pre_l、pre_r三个变量记录上一个值是多少,这样再判断 a + l + r =0 时,

    还需判断 ! (pre_l == l and pre_r == r ) 为真才能添加,最外层 如果 a==pre_a,跳过a这个元素。

    #常规解法
    class Solution:
        def threeSum(self, nums):
            mp = [0]*4*100500
            a = []
            for num in nums:
                if mp[num]==0:
                    a.append(num)
                if mp[num]<2:
                    mp[num]+=1
                elif mp[num] == 2 and num==0:
                    mp[num]+=1
            ans = []
            a = sorted(a)
            idx = {}
            for x in range(len(a)):
                idx[a[x]]=x
            if mp[0]==3:
                ans.append([0,0,0])
            for i in range(len(a)):
                if mp[a[i]]==2 and a[i]!=0:
                    if mp[-2*a[i]]:
                        ans.append([a[i],a[i],-2*a[i]])
                for j in range(i+1,len(a)):
                    tmp = a[i]+a[j]
                    if mp[-tmp] and idx[a[i]]<idx[a[j]]<idx[-tmp]:
                        ans.append([a[i],a[j],-tmp])
            return ans
    #
    #双指针解法
    #
    class Solution:
        def threeSum(self, nums):
            a = sorted(nums)
            ans =[]
            inf = int(1e9)
            pre_i = -inf
            #print(a)
            for i in range(len(a)):
                if pre_i==a[i]:
                    continue
                l = i+1
                r = len(a)-1
                pre_l = - inf
                pre_r = inf
                while l<r:
                    if a[i]+a[l]+a[r]==0:
                        if not(a[l]==pre_l and a[r]==pre_r):
                            ans.append([a[i],a[l],a[r]])
                        pre_l = a[l]
                        pre_r = a[r]
                        l+=1
                        r-=1
                    elif a[i]+a[l]+a[r]<0:
                        pre_l = a[l]
                        l+=1
                    else:
                        pre_r = a[r]
                        r-=1
                pre_i = a[i]
            return ans
  • 相关阅读:
    MVC,MVP,MVVM的区别
    jQuery Mobile 实现苹果滑动删除闹钟功能的几点总结
    AngularJS执行流程详解
    基于angularJS的表单验证练习
    jQuery 中 attr() 和 prop() 方法的区别
    天猫消息盒子的CSS实现
    jQuery事件之传递参数
    浅谈js中的垃圾两种回收机制
    js中的DOM操作汇总
    log4net
  • 原文地址:https://www.cnblogs.com/ISGuXing/p/14607699.html
Copyright © 2011-2022 走看看