LeetCode 16: 3Sum Closest

标签:array, medium

问题描述

Given an array nums of n integers and an integer target, find three integers in nums such that the sum is closest to target. Return the sum of the three integers. You may assume that each input would have exactly one solution.

给定包含n个整数的数组nums和整数target,在数组中寻找3个整数,使得3个整数的和与target的值最接近。返回3个整数的和。假设每个输入只有一个解。

例子:
给定数组nums = [-1, 2, 1, -4]和target = 1。
最接近target值的和是2 (-1 + 2 + 1 = 2)。

解决方案

方法一:暴力方法

遍历数组中的任意3个元素,计算其和以及与target的差,选取差最小的和。

class Solution {
public:
    int threeSumClosest(vector<int>& nums, int target) {
        int len = nums.size();
        int minDiff = INT_MAX;
        int closestSum = 0;
        for(int i = 0; i < len - 2; i++) {
            for(int j = i + 1; j < len - 1; j++) {
                for(int k = j + 1; k < len; k++) {
                    int sum = nums[i] + nums[j] + nums[k];
                    int diff = target > sum ? target - sum : sum - target;
                    if(diff < minDiff) {
                        minDiff = diff;
                        closestSum = sum;
                    }
                }
            }
        }
        return closestSum;
    }
};

算法分析

  • 运行时间:256 m
  • 时间复杂度:Θ(n3)。

方法二:排序法

首先对数组进行排序。接着,选定一个元素i作为第一个元素。然后,从数组两端向中间遍历,选取剩下的两个元素j和k。
如果A[i] + A[k] + A[j]的值小于target,则增加j的索引,否则减少k的索引。因为数组是有序的,这里有三种情况:

  • A[j] + A[k] == target - A[i],此时三个元素的和等于target,差值最小;
  • A[j] + A[k] < target - A[i],因此需要增加j的索引,使值增加。
  • A[j] + A[k] > target - A[i],此时只有减少k的索引,才能减少两个元素的和值。
class Solution {
public:
    int threeSumClosest(vector<int>& nums, int target) {
        int len = nums.size();
        int minDiff = INT_MAX;
        int closestSum = 0;
        sort(nums.begin(), nums.end());

        for(int i = 0; i < len - 2; i++) {
            int j = i + 1;
            int k = nums.size() - 1;
            while(j < k) {
                int sum = nums[i] + nums[j] + nums[k];
                int diff = sum - target > 0 ? sum - target : target - sum;
                if (diff < minDiff) {
                    minDiff = diff;
                    closestSum = sum;
                }
                int sum2 = nums[j] + nums[k];
                if (sum2 > target - nums[i]) {
                    k--;
                } else if (sum2 < target - nums[i]) {
                    j++;
                } else {
                    break;
                }
            }
        }
        return closestSum;
    }
};

算法分析

  • 程序运行时间:12ms
  • 排序算法的复杂度为O(nlog(n)),for循环的复杂度为O(n2)。因此,算法的整体时间复杂度为O(n2)。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容