LeetCode 16 最接近的三數之和(數組、雙指針)

題目要求:

給定一個包括 n 個整數的數組 nums 和 一個目標值 target。找出 nums 中的三個整數,使得它們的和與 target 最接近。返回這三個數的和。假定每組輸入只存在唯一答案。

例如,給定數組 nums = [-1,2,1,-4], 和 target = 1.

與 target 最接近的三個數的和爲 2. (-1 + 2 + 1 = 2).

 

 

 

C++代碼:

class Solution {
public:
    int threeSumClosest(vector<int>& nums, int target) {
        int n = nums.size();
        
        sort(nums.begin(), nums.end());
        int diff = INT_MAX;
        int ans;
        for(int i = 0; i < n-2; i++)
        {
            int num_i = nums[i];
            int l = i+1, r = n-1;
            
            if (i > 0 && num_i > 0 && num_i > target) return ans;
            
            while(l < r)
            {
                int sum = num_i + nums[l] + nums[r];
                if (diff > abs(sum - target))
                {
                    ans = sum;
                    diff = abs(sum - target);
                }
                if (sum > target) r--;
                else if (sum < target) l++;
                else return sum;
            }
        }
        
        return ans;
    }
};

 

 

 

 

結果(8ms):

 

 

 

解析:

這題跟之前的第15題求三數之和基本一樣的思路

LeetCode 15 三數之和(數組、雙指針)

多了一個判斷當前的sum和target的差的過程而已,因爲我們要求最接近的三數之和,越接近越好

 

詳細解釋如下:

把nums裏的元素個數賦給n

int n = nums.size();

然後對nums的元素排序

sort(nums.begin(), nums.end());

然後初始化最大的偏差,這裏叫diff,爲INT_MAX

int diff = INT_MAX;

然後定義一個ans,就是最後返回的最接近的三數之和

int ans;

然後就是遍歷每一個元素,從左到右,已經排好序的,和第15題一樣,只遍歷到n-2

for(int i = 0; i < n-2; i++)

首先把第一個元素的值賦給num_i

int num_i = nums[i];

然後跟第15題一樣,第二個元素取第一個元素的下一位,第三個元素取最後一個元素

int l = i+1, r = n-1;

如果第一個元素都比target大了,那麼越加後面的元素,總和越大,直接返回ans即可,ans此時爲空

if (i > 0 && num_i > 0 && num_i > target) return ans;

否則,只要l<r,就執行while循環

while(l < r)

計算當前的三數之和sum

int sum = num_i + nums[l] + nums[r];

如果當前的sum和target之差的絕對值abs(sum - target),比前一次的diff小的話,那麼我們就需要更新ans和diff

ans更新爲當前的sum

diff更新爲當前的sum和target之差的絕對值abs(sum - target)

if (diff > abs(sum - target))
  {
         ans = sum;
         diff = abs(sum - target);
  }

然後我們還需要判斷我們當前的sum和target直接的關係,看到底是比target大還是比target小,我們好對第二個和第三個元素的位置進行更新,具體還是和第15題一樣

if (sum > target) r--;
    else if (sum < target) l++;
    else return sum;

最後注意,該題返回的是int類型的,也就是最接近的三數之和,不需要三個元素,因此最後return ans; 即可

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章