[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

posted @ 2015-09-18 22:04  Ry_Chen  阅读(1417)  评论(0编辑  收藏  举报