Given an array nums
of n integers, are there elements a, b, c in nums
such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.
Note:
The solution set must not contain duplicate triplets.
Example:
Given array nums = [-1, 0, 1, 2, -1, -4],
A solution set is:
[
[-1, 0, 1],
[-1, -1, 2]
]
给定一个数组,选出三元组使其和为0 三元组不能重复。
将数组排序,固定第一个指针k来进行遍历,然后利用双指针i,j分别从数组k+1--len-1向中点寻找,
当sum=nums[k]+nums[i]+nums[j]==0 直接输出
当sum<0,说明过小,此时移动i指针即可,i++,否则移动j即可,j--
def threeSum(nums=[-2,0,0,2,2]):
nums.sort()
#print(nums)
rr = []
for k in range(len(nums)-1):
i = k+1
j = len(nums)-1
while i<j:
#print(k, i, j)
sum = nums[k] + nums[i] + nums[j]
if sum==0:
rr.append([nums[k], nums[i], nums[j]])
i += 1
j -= 1
elif sum<0:
i += 1
else:
j -= 1
return rr
代码如上所示,输出结果并没有去除重复结果,现在考虑一下重复值的产生情况:
给定数组以及三个指针k,i,j 0---k---i----j---len-1
当nums[k-1]==nums[k]相同时,可以直接k++,进行下一次循环,否则可能会产生重复 例如 -1 -1 0 1 1当k=0与k=1时会产生重复;
当k遍历依次递加没有重复,考虑i位置的重复,当某一元组(k,i,j)符合条件时,此时如果nums[i+1]==nums[j],此时如果执行i++,j--,可能会产生重复,处理方式是当找到符合条件的三元组时,此时应该移动i,j的指针直到nums[i·]不等于nums[i],以及nums[j`]不等于nums[j]
def threeSum(nums=[-2,0,0,2,2]):
nums.sort()
#print(nums)
rr = []
for k in range(len(nums)-1):
if k>=1 and nums[k-1]==nums[k]:
continue
i = k+1
j = len(nums)-1
while i<j:
#print(k, i, j)
sum = nums[k] + nums[i] + nums[j]
if sum==0:
rr.append([nums[k], nums[i], nums[j]])
while i<j and nums[i+1]==nums[i]:
i += 1
while i<j and nums[j-1]==nums[i]:
j -= 1
i += 1
j -= 1
elif sum<0:
i += 1
else:
j -= 1
return rr
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:
Given array nums = [-1, 2, 1, -4], and target = 1.
The sum that is closest to the target is 2. (-1 + 2 + 1 = 2).
给定数组,找到一个三元组,使其和最接近target.
将数组排序,维持一个全局最小差值,利用数组有序以及三指针来调整位置,寻找可能的最小差值
def threeSumClosest(nums=[-4,-1,1,2], target=1):
"""
:type nums: List[int]
:type target: int
:rtype: int
"""
nums.sort()
minv = nums[0]+nums[1]+nums[-1]
mind = abs(nums[0]+nums[1]+nums[-1]-target)
#print(minv, mind)
for k in range(len(nums)):
i = k+1
j = len(nums)-1
while i<j:
diff = nums[k] + nums[i] + nums[j] - target
#print(k,i,j,diff,mind)
if diff==0:
return target
else:
if abs(diff)<=mind:
minv = nums[k] + nums[i] + nums[j]
mind = abs(diff)
#print(minv, mind)
if diff<0:
i += 1
else:
j -= 1
return minv
Given an array nums
of n integers and an integer target
, are there elements a, b, c, and d in nums
such that a + b + c + d = target
? Find all unique quadruplets in the array which gives the sum of target
.
Note:
The solution set must not contain duplicate quadruplets.
Example:
Given array nums = [1, 0, -1, 0, -2, 2], and target = 0.
A solution set is:
[
[-1, 0, 0, 1],
[-2, -1, 1, 2],
[-2, 0, 0, 2]
]
给定一个数组,寻找非重复四元组使其和等于target.
类似于三元组和问题,如果暴力求解时间复杂度为N4.
首先将数组排序,数组变为有序之后。利用两个指针来遍历前两个元素,后面再利用双指针从头尾向中间递进,依次寻找符合条件的组合解,将时间复杂度降为N2logN
class Solution:
def fourSum(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[List[int]]
"""
nums.sort()
rr = []
for k in range(len(nums)):
if k>0 and nums[k]==nums[k-1]:
continue
for m in range(k+1, len(nums)):
if m>k+1 and nums[m]==nums[m-1]:
continue
i=m+1
j=len(nums)-1
while i<j:
sum=nums[k]+nums[m]+nums[i]+nums[j]
if sum==target:
rr.append([nums[k],nums[m],nums[i],nums[j]])
while i<j and nums[i]==nums[i+1]:
i += 1
while i<j and nums[j]==nums[j-1]:
j -= 1
i += 1
j -= 1
elif sum<target:
i += 1
else:
j -= 1
return rr
去重要考虑四个指针的去重,k,m分别从头向尾遍历,因此去重要考虑每一个元素与前一个元素是否相同,如果相同则直接跳过进行下一个元素遍历;i,j分别从头尾向中间遍历递进,当找到符合条件的元组时,i,j应该继续向中间逼近,直到取到新的不同于上一个值为止,继续进行求和与target的大小判断,即可去重。