2023-07-15 LeetCode の毎日の質問 (4 つの数字の合計)

2023-7-15 1 日 1 つの質問

1. トピック番号

18. 四数之和

2. トピックリンク

クリックするとトピックの場所にジャンプします

3. トピックの説明

n 個の整数の配列 nums とターゲット値 target が与えられます。次のすべての条件を満たし、繰り返されない四倍子 [nums[a], nums[b], nums[c], nums[d]] を見つけて返してください (2 つの 4 倍要素が 1 対 1 に対応する場合、2 つ4 倍は繰り返されるとみなされます):

  • 0 <= a、b、c、d < n
  • a、b、c、dはそれぞれ異なります
  • nums[a] + nums[b] + nums[c] + nums[d] == target回答は任意の順序
    で返すことができます

ヒント:

  • 1 <= nums.length <= 200
  • -10 9 <= nums[i] <= 10 9
  • -10 9 <= ターゲット <= 10 9

4. 問題解決コード

class Solution {
    
    
public:
    vector<vector<int>> fourSum(vector<int>& nums, int target) {
    
    
        vector<vector<int>> res;
        int n = nums.size();
        if(n < 4){
    
    
            return res;
        }
        sort(nums.begin(), nums.end());
        for(int i = 0; i < n; ++i){
    
    
            while(i != 0 && i < n && nums[i] == nums[i-1]){
    
    
                ++i;
            }
            for(int j = i + 1; j < n; ++j){
    
    
                while(j != i + 1 && j < n && nums[j] == nums[j - 1]){
    
    
                    ++j;
                }
                int left = j + 1;
                int right = n - 1;
                while(left < right){
    
    
                    long long temp = (long long)nums[left] + nums[right] + nums[i] + nums[j];
                    if(temp < target){
    
    
                        ++left;
                    } else if(temp == target){
    
    
                        res.push_back({
    
    nums[i], nums[j], nums[left], nums[right]});
                        ++left;
                        --right;
                        while(left <= right && nums[left] == nums[left - 1]){
    
    
                            ++left;
                        }
                        while(left <= right && nums[right] == nums[right + 1]){
    
    
                            --right;
                        }
                    } else{
    
    
                        --right;
                    }
                }
            }
        }
    return res;
    }
};

5、問題解決のアイデア

(1) このトピックは3 つの数の和の発展版であり、3 つの数の和とあまり変わりません。3 つの数の和がわからない場合は、この記事を読んでください— 2023-07 -08 LeetCode 毎日 1 つの質問 (3 つの数字の合計)

(2) 同じ考え方ですが、問題は 4 つの数を見つけることであり、繰り返されていないものが目標に等しいです。次に、元の配列を最初に並べ替えます。これは、繰り返しを避けるのに役立ちます。

(3) 4 層ループ + ハッシュ判定法を使用すると、非常に時間計算量が高く、問題を通過できないはずです。したがって、私たちは住むのに適した別の木を選ばなければなりません。最初の数値をトラバースするように最も外側のループを設定します。結果の最初の数値を異なるものにするには、その数値が前の数値と同じである場合、その数値が値になる可能性がすべて判明していることになります。は必要ありません。最初の数値も同じ値 i++ です。

(4) このとき、問題を 3 つの数値の合計の問題に変換しましたが、求めている数値の合計は target と等しくなく、target - nums[i] と等しくなります。3つの数字の合計についてはこの記事で詳しく書いているので、詳しくは説明しません。ただし、大まかな考え方は (3) と同じで、繰り返しを行わない方法で、数値が 2 つしか残っていない場合は、ダブル ポインター法を使用して時間を短縮します。

おすすめ

転載: blog.csdn.net/qq_56086076/article/details/131734309