这两个题非常相似,所以放在一起了
题目
Given an integer array nums, return all the triplets [nums[i], nums[j], nums[k]]
such that i != j
, i != k
, and j != k
, and nums[i] + nums[j] + nums[k] == 0
.
Notice that the solution set must not contain duplicate triplets.
Example 1:
Input: nums = [-1,0,1,2,-1,-4]
Output: [[-1,-1,2],[-1,0,1]]
Example 2:
Input: nums = []
Output: []
Example 3:
Input: nums = [0]
Output: []
Constraints:
0 <= nums.length <= 3000
-105 <= nums[i] <= 105
解法:
解法一:
解法一的时间复杂度是,因为最近主要在练习python,所以贴评论区python解法
def threeSum(self, nums):
res = []
nums.sort()
for i in xrange(len(nums)-2):
#去重,因为nums[i-1]的时候,已经将[i,len(nums)-1]范围内所有可能的组合都添加到结果集中#了。如果nums[i]的可能结果集范围比nums[i-1]小,为[i+1,len(nums)-1]。如果nums[i]=nums[i-#1],则需跳过nums[i]防止重复。
if i > 0 and nums[i] == nums[i-1]:
continue
l, r = i+1, len(nums)-1#分别是左右两个指针
while l < r:
s = nums[i] + nums[l] + nums[r]
if s < 0:#因为nums已经从小到大排好了,当和小于0时,就希望用更大的值,所以左边加一
l +=1
elif s > 0:#当和大于0时,希望用更小的值,所以右边减一
r -= 1
else:
res.append((nums[i], nums[l], nums[r]))
while l < r and nums[l] == nums[l+1]:#去重
l += 1
while l < r and nums[r] == nums[r-1]:#去重
r -= 1
l += 1; r -= 1
return res
解法二:
我自己的思路,算法复杂度是,在倒数第三个案例会跑不过去,超时。和解法一的区别在于找第二第三个元素时,我是固定第三个元素,用二分法找第二个元素,复杂度O(nlogn)。而解法一是从两边向中间遍历,复杂度为O(n)。
我的算法每次固定左边的元素i和右边的元素j,然后用二分法找中间的元素。就这个题而言是无法ac的,倒数第三个测试案例通不过,超时。就是记录下自己的想法
def threeSum(self, nums: List[int]) -> List[List[int]]:
result=[]
if(nums is None or len(nums)<3):
return result
nums.sort()
start=stop=0
for i in range(0,len(nums)-2):#左边的数
#去重
if(i>0 and nums[i]==nums[i-1]):
continue
start=I#二分法的左端
for j in range(len(nums)-1,i+1,-1):#右边的数
if (j < len(nums) - 1 and nums[j + 1] == nums[j]):#去重
continue
stop=j#二分法的右端
p=(i+j)//2#中间的数
while(p>i and p<j):
if(nums[i]+nums[j]+nums[p]==0):
result.append([nums[i],nums[p],nums[j]])
break
elif(nums[i]+nums[j]+nums[p]>0):
stop=p
p=(p+start)//2
else:
if(p==stop-1):#防止死循环
break
start=p
p=(p+stop)//2
return result
16. 3Sum Closest题目
Given an array nums
of n integers and an integer target
, find three integers in nums
such that the sum is closest to target
. Return the sum of the three integers. You may assume that each input would have exactly one solution.
Example 1:
Input: nums = [-1,2,1,-4], target = 1 Output: 2 Explanation: The sum that is closest to the target is 2. (-1 + 2 + 1 = 2).
Constraints:
3 <= nums.length <= 10^3
-10^3 <= nums[i] <= 10^3
-10^4 <= target <= 10^4
解法:
这个跟15题太相似了,直接贴O()解法,这个代码精简很多,因为题目中讲了有且仅有一个答案,不用考虑去重或者为空的情况。
def threeSumClosest(self, num, target):
num.sort()
result = num[0] + num[1] + num[2]
for i in range(len(num) - 2):
j, k = i+1, len(num) - 1
while j < k:
sum = num[i] + num[j] + num[k]
if sum == target:
return sum
if abs(sum - target) < abs(result - target):
result = sum
if sum < target:
j += 1
elif sum > target:
k -= 1