目录
LeetCode 第16题 最接近的三数之和
题目
解题思路
代码
结果
LeetCode 第18题 四数之和
题目
解题思路
代码
结果
LeetCode 第16题 最接近的三数之和
题目
给你一个长度为 n
的整数数组 nums
和 一个目标值 target
。请你从 nums
中选出三个整数,使它们的和与 target
最接近。
返回这三个数的和。
假定每组输入只存在恰好一个解。
示例 1:
输入:nums = [-1,2,1,-4], target = 1 输出:2 解释:与 target 最接近的和是 2 (-1 + 2 + 1 = 2) 。
示例 2:
输入:nums = [0,0,0], target = 1 输出:0
提示:
3 <= nums.length <= 1000
-1000 <= nums[i] <= 1000
-104 <= target <= 104
解题思路
此题目同上次的三数之和问题解法大致相同,很多leetcode题目近似题目的解法都是互通的
代码之旅:我的算法探索之路(一)力扣 两数之和 三数之和问题-CSDN博客
- 首先对数组进行排序,因为我们要动态的根据当前值和target的差距,来变化我们的三个指针,使得我们的三个数之和能认为更加接近target
- 然后,我们进行range遍历,注意要点就是遍历的终点是len(nums) - 2,因为我们要保证能够组成三个数字的三元组
- 接下来,初始化left,right的逻辑为left = i - 1 以及right = len(nums) - 1
- 为了遍历所有的可能,我们通过while循环来实现,while循环的逻辑是当left小于right,不能等于,因为此时三个数就重了,不能大于,否则三元组就重复了
- 我们会维护一个初始值为无穷大的值,在python通过closest_sum = float('inf')实现,当作最接近target的sum结果,然后不断更新这个值
代码
class Solution:
def threeSumClosest(self, nums, target):
nums.sort()
closest_sum = float('inf')
for i in range(len(nums) - 2):
left, right = i + 1, len(nums) - 1
while left < right:
current_sum = nums[i] + nums[left] + nums[right]
if abs(current_sum - target) < abs(closest_sum - target):
closest_sum = current_sum
if current_sum < target:
left += 1
elif current_sum > target:
right -= 1
else:
return target
return closest_sum
结果
LeetCode 第18题 四数之和
题目
给你一个由 n
个整数组成的数组 nums
,和一个目标值 target
。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]]
(若两个四元组元素一一对应,则认为两个四元组重复):
0 <= a, b, c, d < n
a
、b
、c
和d
互不相同nums[a] + nums[b] + nums[c] + nums[d] == target
你可以按 任意顺序 返回答案 。
示例 1:
输入:nums = [1,0,-1,0,-2,2], target = 0 输出:[[-2,-1,1,2],[-2,0,0,2],[-1,0,0,1]]
示例 2:
输入:nums = [2,2,2,2,2], target = 8 输出:[[2,2,2,2]]
提示:
1 <= nums.length <= 200
-109 <= nums[i] <= 109
-109 <= target <= 109
解题思路
此题目和三数之和求解非常之像
代码之旅:我的算法探索之路(一)力扣 两数之和 三数之和问题-CSDN博客
针对此题仍然采用双指针的思想
常规解题暴力解法需要4重循环,双指针相当于替代了两重循环,时间复杂度更优
- 首先对数组进行排序,使得我们可以动态根据target的大小比较来决定双指针移动方向
- 第一重循环要设置终点是nums数组长度-3,因为要保证有四个数字构成四元组
- 接下来进行判重逻辑,如果此数字和上个位置数字一样,则此轮跳过,因为上重就处理了此数字的四元组结果了
- 第二重for循环和判重同第一重for循环一致
- 接下来是不断移动两个指针,同寻找三数之和一样
- 现在之和大于target,则要让四元组变小,right左移,反之left右移
- 两轮判重逻辑,如果left,right指针路径上连续几个数字都一样,则跳过避免重复
代码
class Solution(object):
def fourSum(self, nums, target):
nums.sort()
results = []
for i in range(len(nums) - 3):
if i > 0 and nums[i] == nums[i - 1]:
continue
for j in range(i + 1, len(nums) - 2):
if j > i + 1 and nums[j] == nums[j - 1]:
continue
left = j + 1
right = len(nums) - 1
while(left < right):
total = nums[i] + nums[j] + nums[left] + nums[right]
if total < target:
left += 1
elif total > target:
right -= 1
else:
results.append([nums[i], nums[j], nums[left], nums[right]])
while left < right and nums[left] == nums[left + 1]:
left += 1
while left < right and nums[right] == nums[right - 1]:
right -= 1
left += 1
right -= 1
return results