思路:先排序,取出大于等于0,小于0两个数组,在两个数组里各自取出一个值求和,在剩下的数字中找到与之互补的数字。
1、排序
2、将数据分为两个列表,一个为负数,一个为正数和0
3、在剩下的数中找和这两个数相加为0 的数
算法复杂度O(n^2*logn)
from typing import List
class Solution:
def threeSum(self, nums: List[int]) -> List[List[int]]:
#二分查找法
def dichotomyFind(L, target):
length = len(L)
high = length - 1
low = 0
while (high >= low):
if (L[int((high + low) / 2)] > target):
high = int((high + low) / 2) - 1
elif L[int((high + low) / 2)] < target:
low = int((high + low) / 2) + 1
else:
out = L[int((high + low) / 2)]
return out
return 100001
#正负数分类 并排序
result = []
zero = nums.count(0)
if(zero>=3): #得到三个都为0的答案
result.append([0,0,0])
Snums = nums.copy()
Snums.sort() #排序
length = len(nums)
count = 0
for i in Snums:
if i < 0:
count += 1
if i >= 0:
break;
small = Snums[0:count]
big = Snums[count:length]
for i in range(0, len(small)): #从负数集合寻找点
for j in range(len(big)-1, -1,-1): #把最大的正数放进去
target = -small[i] - big[j]
if small[i] + big[j] <= 0:
res = dichotomyFind(big[0:j], target)
#print(res)
else:
res = dichotomyFind(small[i+1:len(small)],target)
#print(res)
if res != 100001:
re = [small[i], big[j], res]
re.sort()
if (re in result):
continue
else:
result.append(re)
while j-1>-1:
if(big[j-1] == big[j]):
j = j - 1
else:
break
while i + 1 < len(small):
if (small[i+1] == small[i]):
i=i+1
else:
break
return result
nums = [1]
# #nums = [-1,0,1,2,-1,-4]
out = Solution().threeSum(nums)
print(out)
这个方法在解答的时候,是超出时间的。时间复杂度O(n^2logn)
from typing import List
class Solution:
def threeSum(self, nums: List[int]) -> List[List[int]]:
if(len(nums)<3):
return []
nums.sort() #对列表进行排序
result = []
for i in range(0,len(nums)):
L = i+1
R = len(nums)-1
while(L<R):
if(nums[i]+nums[L]+nums[R]<0):
L+=1
elif(nums[i]+nums[L]+nums[R]>0):
R-=1
else:
re = [nums[i],nums[L],nums[R]]
L += 1
R -= 1
re.sort()
if(re not in result):
result.append(re)
return result
时间复杂度O(n^2)