本题和盛水最多的容器这个题目非常的类似,我就不做过多的铺垫了,我们一起来看题目和我的解题思路吧。
最接近的三个数之和
题目
给定一个包括 n 个整数的数组 nums 和 一个目标值 target。找出 nums 中的三个整数,使得它们的和与 target 最接近。返回这三个数的和。假定每组输入只存在唯一答案。
示例:
输入:nums = [-1,2,1,-4], target = 1 输出:2
解释:与 target 最接近的和是 2 (-1 + 2 + 1 = 2) 。
提示:
3 <= nums.length <= 10^3 -10^3 <= nums[i] <= 10^3 -10^4 <= target <= 10^4
解题分析
解题思路:
如果采用暴力解题的办法时间复杂度是 O(N * N *N), 这样解题肯定是无法通过的。
对于这样的题目我们可以采用排序 + 双指针的方式来解。
- 首先我们对于第一个数肯定是需要进行枚举的,为了更好的控制数据的大小,我们需要先对数组进行排序
- 这样我们就可以通过将求三个数的和,转化为求两个数的和。我们可以采用双指针的方法。进行遍历。这样时间复杂度就可以降低为 O(N*N)。
解题答案
public class ThreeSumClosestTest {
public static void main(String[] args) {
ThreeSumClosestTest test = new ThreeSumClosestTest();
test.threeSumClosest(new int[]{1, 2, 3, 4}, 1);
}
public int threeSumClosest(int[] nums, int target) {
// 数组长度
int len = nums.length;
// 排序
Arrays.sort(nums);
int result = Integer.MAX_VALUE - target;
for (int i = 0; i < len - 2; i++) {
// left, right 表示两端的指针
int left = i + 1, right = len - 1;
// 始终保证左边的指针小于右边的指针
while (left < right) {
// 三个数求和
int sum = nums[i] + nums[left] + nums[right];
// 情况 1,如果相等直接返回
if (sum == target) {
return sum;
// 情况 2,如果大于目标值
} else if (sum > target) {
// 判断是否比 result 更加接近 target
if (Math.abs(sum - target) < Math.abs(result - target)) {
// 替换 target
result = sum;
}
// 右指针左移
right--;
} else {
if (Math.abs(sum - target) < Math.abs(result - target)) {
result = sum;
}
// 左指针右移
left++;
}
}
}
return result;
}
}