16 3つの数値の最も近い合計(ソート、ダブルポインター)

1.問題の説明:

n個の整数numsの配列とターゲット値targetを指定します。それらの合計がターゲットに最も近くなるように、nums内の3つの整数を見つけます。これら3つの数値の合計を返します。入力の各グループに対して一意の回答は1つしかないと想定されています。

たとえば、配列nums = [-1、2、1、-4]、およびtarget = 1が与えられます。

ターゲットに最も近い3つの数値の合計は2です(-1 + 2 + 1 = 2)。

出典:LeetCode
リンク:https ://leetcode-cn.com/problems/3sum-closest

2.思考分析:

①この問題は、3つの数値合計の以前の問題と非常に似ているため、3つの数値の合計を処理する以前の方法を使用して解決できますが、これは以前の処理の詳細とは異なります。解決するプロセスで解決する必要があります。 3つの数値の現在の合計の最小値とターゲット値の絶対値、および3つの数値の過去の合計の最小値とターゲット値の最小値を更新するかどうかを決定します

②配列を最初に並べ替えます。取得した要素が同じである場合は、強調を解除する必要はありません。最終的な結果には影響しません。前の3つの数値の合計に基づいて変更されるだけなので、重複排除コードを削除します。ここでは、境界に特別な注意を払う必要があります。並べ替え後、ターゲット値は、配列の左側の3桁の合計よりも小さいか、配列の右側の3桁の合計よりも大きくなります。その後、この時間に直接戻ることができます。境界上の3つの要素がターゲット要素に最も近い。このステップで処理が行われず、ループ内でダブルポインタ操作が実行された場合、結果は正しくない

3.コードは次のとおりです。

class Solution {
    public int threeSumClosest(int[] nums, int target) {
        Arrays.sort(nums);
        /*使用之前的三数之和的双指针的代码修改一下*/
        if (target <= nums[0] + nums[1] + nums[2]) return nums[0] + nums[1] + nums[2];
        else if (target >= nums[nums.length - 3] + nums[nums.length - 2] + nums[nums.length - 1]) return nums[nums.length - 3] + nums[nums.length - 2] + nums[nums.length - 1];
        int len = nums.length;
        int res = Integer.MAX_VALUE;
        for (int a = 0; a <= len - 3; ++a){
            //去重
            if (a > 0 && nums[a] == nums[a - 1]) continue;
            int b = a + 1, c = len - 1;
            while (b < c){
                int cur = nums[a] + nums[b] + nums[c];
                if (cur < target) {
                    ++b;
                    if(Math.abs(target - cur) < Math.abs(target - res))
                        res = cur;
                }
                else if (cur > target) {
                    --c;
                    if(Math.abs(target - cur) < Math.abs(target - res))
                        res = cur;
                }
                else  return cur;
            }
        }
        return res;
    }
}

首輪ボタンで良いものを見つけました。このコードはダブルポインターを使用した暴力に基づいて最適化されているように感じますが、それでも非常に優れており、理解しやすくなっています。

class Solution {
    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) {
                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;
    }
}

 

元の記事569件を公開 153のような 訪問数590,000+

おすすめ

転載: blog.csdn.net/qq_39445165/article/details/105444918