最接近的三数之和(Java)

探讨了在给定数组中寻找三个整数,使其和最接近特定目标值的算法。介绍了暴力法及其优化,通过排序和双指针技术提高效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述

给定一个包括 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^3)。暴力解法很少会成为我们最终满意的答案,效率十分低下。那为什么还要写暴力解法。首先暴力解法可以让我们发现代码在什么方面还有优化的空间,二来,暴力解法可以为我们提供一个正确答案的参考,因为暴力解法的计算出的答案肯定是没问题的。

 public static int threeSumClosest2(int[] nums, int target) {
        int ans=3001;
        for (int left = 0; left < nums.length - 2; left++) {
            for (int mid = left + 1; mid < nums.length - 1; mid++) {
                for (int right = mid + 1; right < nums.length; right++) {
                    int sum=nums[left]+nums[mid]+nums[right];
                    ans=Math.abs(sum-target)<Math.abs(ans-target)?sum:ans;
                }
            }
        }
        return ans;
    }

暴力法优化

题目要求选择三个数,若是我们对数组排好序,那么我们就可以像二分查找那样,三个数之和大于目标数则抛弃一个较大的数字选择一个更小的数字,若是小于目标数字则抛弃一个较小的数字选择一个较大的数字。

排序后,我们依次枚举最小数字作为第一个数字,然后选择数组中的最大值作为第三个数字。第二个数字则在最小数字和最大数字中间。若三个数字和较大则指向最大数字的指针前移,否则指向中间数字的指针后移。

 public static int threeSumClosest(int[] nums, int target) {
        Arrays.sort(nums);
        int minAbs = 3001;
        int ans = 0;
        for (int left = 0; left < nums.length; left++) {
            int mid = left + 1, right = nums.length - 1;
            while (mid < right) {
                int sum = nums[left] + nums[mid] + nums[right];
                if (sum > target) {
                    right--;
                    if (sum - target < minAbs) {//更新最接近数字
                        minAbs = sum - target;
                        ans = sum;
                    }
                } else if (sum < target) {
                    mid++;
                    if (target - sum < minAbs) {//更新最接近数字
                        minAbs = target - sum;
                        ans = sum;
                    }
                } else return target;
            }
        }
        return ans;
}

虽然仍然不是最优解,但是效率也还可以,时间复杂度为o(n^2).
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值