leetcode15 题目
给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。
注意:答案中不可以包含重复的三元组。
例如, 给定数组 nums = [-1, 0, 1, 2, -1, -4],
满足要求的三元组集合为:
[
[-1, 0, 1],
[-1, -1, 2]
]
leetcode16 题目
给定一个包括 n 个整数的数组 nums 和 一个目标值 target。找出 nums 中的三个整数,使得它们的和与 target 最接近。返回这三个数的和。假定每组输入只存在唯一答案。
例如,给定数组 nums = [-1,2,1,-4], 和 target = 1.
与 target 最接近的三个数的和为 2. (-1 + 2 + 1 = 2).
为什么把这两个题目放在一起
相信在你读完这两个题目后,会发现这两个题目"非常相似"(前者的target=0 后者的targrt=target 都是三个数),同时肯定是需要一定的技巧的,是不能暴力求解的
大致说一下解题思路(至于实现细节和边缘 大家自己看我的程序哈)
我们可以先对数组进行排序,如果是计算两个元素的和的话,我们会分别设置头和尾两个指针,向中间靠拢,那么三个的话,我们只需要先对第一个数进行循环取值下标i,剩下的两个指针分别指向i+1和数组的最后一个元素,这样的复杂度是 排序O(nlogn) + 查找O(n^2) = O(n^2)。
程序解答 (可以直接跑起来)
leetcode 15
class Solution:
@staticmethod
def threeSum(nums):
"""
:type nums: List[int]
:type target: int
:rtype: int
"""
nums=sorted(nums)
print(nums)
ans=[]
isVisted=[]
for i,num_1 in enumerate(nums):
if num_1 in isVisted:
continue
else:
isVisted.append(num_1)
print(num_1)
tmp=set()
j=i+1
k=len(nums)-1
while j<k:
num_2=nums[j]
num_3=nums[k]
sum=num_1+num_2+num_3
if sum==0:
if len(tmp)>=1 and (num_2 in tmp):
pass
else:
ans.append([num_1,num_2,num_3]) #没有最小的
tmp.add(num_1)
tmp.add(num_2)
tmp.add(num_3)
j+=1
k-=1
elif sum<0:
j+=1
else:
k-=1
return ans
if __name__=="__main__":
print(Solution.threeSum([0,0,0,0]))
leetcode 16
class Solution:
@staticmethod
def threeSumClosest(nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: int
"""
nums=sorted(nums)
flag=0
ans=0
for i,num_1 in enumerate(nums):
j=i+1
k=len(nums)-1
while j<k:
num_2=nums[j]
num_3=nums[k]
sum=num_1+num_2+num_3
if flag==0:
flag=1
ans=sum
if abs(sum-target)<abs(ans-target):
ans=sum
if sum==target:
return ans #没有最小的
elif sum<target:
j+=1
else:
k-=1
return ans
if __name__=="__main__":
print(Solution.threeSumClosest([-1,2,1,-4],1))