夯实算法-最接近的三数之和

99 阅读1分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 3 天,点击查看活动详情

题目:LeetCode

给你一个长度为 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-10^4 <= target <= 10^4

解题思路

根据题意分析是一个典型的双指针问题,就是在一个排好序的数组中寻找两个元素,和等于某个值。

在这道题中,我们要寻找的是符合条件的一对下标 (i,j)(i,j),它们需要满足的约束条件是: i、j 都是合法的下标,即 0i<n0≤i<n,0j<n0≤j<n i<ji<j(题目要求) 而我们希望从中找到满足 A[i]+A[j]==targetA[i] + A[j] == target 的下标 (i,j)(i,j)

当前题目问的是三个数,其和最接近targettarget,和寻找元素和精准地等于targettarget没什么区别。无非是比较absabs值,三个数,就是一个数+两个数,前者直接遍历,后者使用双指针来寻找。

代码实现

public int threeSumClosest(int[] nums, int target) {
    Arrays.sort(nums); // 先将数组排序
    int ans = nums[0] + nums[1] + nums[2];
    for (int i = 0; i < nums.length; i++) { // 在这个排好序的数组中进行遍历
        int start = i + 1, end = nums.length - 1; // 首尾双指针
        while (start < end) { //当i为数组的最后一个下标时,start 就是nums.length-1, 自然就不会展开这个while循环了。
            int sum = nums[start] + nums[end] + nums[i];
            if (Math.abs(target - sum) < Math.abs(target - ans))
                ans = sum;
            if (sum > target)
                end--;
            else if (sum < target)
                start++;
            else
                return ans;
        }
    }
    return ans;
}

运行结果

Snipaste_2023-02-06_23-17-58.png

复杂度分析

  • 空间复杂度:O(1)O(1)
  • 时间复杂度:O(n)O(n)

掘金(JUEJIN)  一起分享知识, Keep Learning!