携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第19天,点击查看活动详情
题目描述
给你一个长度为 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
题目元素
给定一个长度为n的正数数组,和正数target。返回数组中的三个元素,使这三个元素之和最接近target
解题思路
首先,要确定题目类型。是从数组中找出元素使它能够满足条件,而且条件中是包含最值的,找出距离差距最小的三个元素,所以需要先将数组进行排序,这里可以将数组进行升序排序(降序也可以)。
然后确定采用什么方式来查找这三个元素。这道题其实也属于排列组合的问题,同一个组合不能有相同坐标的元素,排列组合的题可以采用指针的方式去求解。这道题可以先固定第一个元素,剩下的两个元素采用左右指针的方式,第一个指针在固定元素的右边第一个位置,第二个指针在数组的最后一个位置,然后依次向内收紧。
这里的收紧条件可以提高查询效率。数组是按照升序排列的,这里求的是最近的三个元素;
- 如果固定元素+第一个指针元素+第二个指针元素>target,则第二个指针向左移动;
- 如果固定元素+第一个指针元素+第二个指针元素<target,则第一个指针元素向右移动;
- 如果固定元素+第一个指针元素+第二个指针元素=target,则直接返回这三个元素。
代码实现
/**
* @param nums
* @param target
* @return
*/
public static int threeSumClosest(int[] nums, int target) {
Arrays.sort(nums);
// 固定元素
int min = Integer.MAX_VALUE;
int res = 0;
for (int i =0 ;i < nums.length-2;i ++) {
// 固定元素为i
// 左指针
int left = i+1;
// 右指针
int right = nums.length-1;
while (left < right) {
// 双指针移动
int nowCount = nums[i] + nums[left] + nums[right];
if (min > Math.abs(target - nowCount)) {
min = Math.abs(target - nowCount);
res = nowCount;
}
if (nowCount > target) {
// 右指针向左移动
right -- ;
} else if (nowCount < target) {
// 左指针向右移动
left ++;
} else {
// 直接返回三个元素
return target;
}
}
}
return res;
}