leetcode刷题日记-【16. 最接近的三数之和】

100 阅读1分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 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;
}