[Leetcode16]最接近的三数之和
[Leetcode16]最接近的三數之和
轉載自leetcode
https://leetcode-cn.com/problems/3sum-closest/
1.題目
給定一個包括 n 個整數的數組 nums 和 一個目標值 target。找出 nums 中的三個整數,使得它們的和與 target 最接近。返回這三個數的和。假定每組輸入只存在唯一答案。
2.解題思路
這是一道數組搜索題,需要找到滿足題意的三個整數,并返回他們的和。
分析:
idea1. 如果使用暴力遍歷,顯然需要三重循環,是不可取的。
idea2. 數組搜索常常可以使用左右指針加快搜索速度。通常使用雙指針搜索會先對數據進行一次排序。
解題步驟:
step1. qsort排序
step2. 假設輸出應該是sum = nums[a] + nums[left] + nums[right],升序遍歷a,搜索在每個a下雙指針最優解
step3. 令左指針left = a+1, 右指針right = numsSize - 1。比較當前sum和target關系。
step4. 當sum小于target時,需要增加左指針 left++,當sum大于target時,需要減少右指針right--,繼續遍歷
step5. 雙指針搜索終止條件 left >= right。此時sum有當前a下最優解。重復 step 2 - 4。
step6. 遍歷a 從 0 至 numsSize - 1。輸出最優解sum
優化:
該題在解題步驟上應該有很多優化思路:
例如,遇到sum = target時,直接退出遍歷。
例如,遇到相同數據時候可以跳過判斷,減少遍歷次數。
例如,當a + right 和target差大于sum和target差時,可以退出遍歷。
可信:
(針對于存在數據溢出風險的代碼來說),由于res需要初始化為 INT_MAX = 2^31 - 1。因此計算時需要定義為long型
3.算法
排序 + 雙指針
4.C代碼
int cmp(const void *a, const void *b) {return *(int *)a - *(int *)b; }long get_abs(long num) {return (num > 0) ? num : (0 - num); }int threeSumClosest(int* nums, int numsSize, int target){qsort(nums, numsSize, sizeof(nums[0]), cmp);int a = 0, b = 1, c = numsSize - 1;long int sum;long int res = INT_MAX;if (numsSize == 3)return nums[a] + nums[b] + nums[c];for (a = 0; a < numsSize - 2; a++) {if (a > 0 && nums[a] == nums[a - 1])continue;b = a + 1;c = numsSize - 1;while (b < c) {sum = nums[a] + nums[b] + nums[c];if (sum < target) {res = (get_abs(res - target) < get_abs(sum - target)) ? res : sum;while (b < c && nums[b] == nums[++b]); //b++;}else if (sum > target) {res = (get_abs(res - target) < get_abs(sum - target)) ? res : sum;while (b < c && nums[c] == nums[--c]);//c--;}else {return sum;}}}return res; }總結
以上是生活随笔為你收集整理的[Leetcode16]最接近的三数之和的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: main()函数参数
- 下一篇: oracle非常量不能用于privot_