zoukankan      html  css  js  c++  java
  • [LeetCode]题解(python):015-3Sum

    题目来源:

    https://leetcode.com/problems/3sum/


    题意分析:

         这道题目是输入一个数组nums。找出所有的3个数使得这3个数之和为0.要求1.输出的3个数按小到大排序,2.3个数的组合不重复。比如输入[-1,0,1,2,-1,-4],返回的应该是[[-1,0,1],[-1,-1,2]]。


    题目思路:

        如果直接暴力解决,那么时间复杂度是(O(n^3))。这样会TLE。

        看到这道题目,我回想了leetcode的第一题。第一题是给出一个数组和一个target,找出数组的两个数使得这两个数等于target。在第一题中,我提到了”夹逼定理“。这里这个定理就可以用了。首先,我们将输入的数组nums排序。然后,从头开始取出一个数,nums[i],在nums[i+1:]中用夹逼定理找出num[j],nums[k](j<k)使得他们的和为0- nums[i]。然后将[nums[i],nums[j],nums[k]] append到答案数组。由于会存在多个组合使得nums[i] + nums[j] + nums[k] = 0,所以在比较的时候,如果nums[j] + nums[k] < 0- nums[i]时候,j += 1;如果nums[j] + nums[k] > 0 - nums[i]时候,k -= 1;如果nums[j] + nums[k] == 0 - nums[i]的时候,一直j += 1,k -= 1直到nums[j] != nums[j - 1]和nums[k] != nums[k + 1]。要注意的是,为了避免出现重复的组合,那么i + 的时候也要一直加到nums[i] != nums[i - 1]

        这种方法中,排序的时间复杂度是(O(n*log(n))),夹逼定理的时间复杂度是(O(n)),取数复杂度是(O(n)),总的时间复杂度是(O(n*log(n)) + O(n)*O(n)) = O(n^2)。所以时间复杂度是O(n^2)。


    代码(python):

     1 class Solution(object):
     2     def threeSum(self, nums):
     3         """
     4         :type nums: List[int]
     5         :rtype: List[List[int]]
     6         """
     7         size = len(nums)
     8         ans = []
     9         if size <= 2:
    10             return ans
    11         nums.sort()
    12         i = 0
    13         while i < size -2:
    14             tmp = 0 - nums[i]
    15             j = i + 1
    16             k = size -1
    17             while j < k:
    18                 if nums[j] + nums[k] < tmp:
    19                     j += 1
    20                 elif nums[j] + nums[k] > tmp:
    21                     k -= 1
    22                 else:
    23                     ans.append([nums[i],nums[j],nums[k]])
    24                     j += 1
    25                     k -= 1
    26                     while j < k:
    27                         if nums[j] != nums[j - 1]:
    28                             break
    29                         if nums[k] != nums[k + 1]:
    30                             break
    31                         j += 1
    32                         k -= 1
    33             i += 1
    34             while i < size - 2:
    35                 if nums[i] != nums[i - 1]:
    36                     break
    37                 i += 1
    38         return ans
    View Code

    转载请注明出处:http://www.cnblogs.com/chruny/p/4820473.html

  • 相关阅读:
    hdu_2842_Chinese Rings(矩阵快速幂)
    hdu_3565_Bi-peak Number(数位DP)
    hdu_1536_S-Nim(DFS_SG博弈)
    hdu_1848_Fibonacci again and again(博弈sg函数)
    hdu_2147_kiki's game(博弈)
    hdu_2955_Robberies(01背包)
    hdu_5705_Clock("巴卡斯杯" 中国大学生程序设计竞赛
    [POJ2104]K-th Number
    【AHOI2014复仇】
    最长回文子串
  • 原文地址:https://www.cnblogs.com/chruny/p/4820473.html
Copyright © 2011-2022 走看看