ニラ: 2 つの数の合計と 3 つの数の合計と 4 つの数の合計

1. 2 つの数値の合計:

アイデア: map を使用してトラバースされたデータを格納します。つまり、map を使用して、トラバース中にトラバースされた要素を格納し、マップ内に探している別の数値があるかどうかを確認します。注: マップでは、
1 を使用します。マップの基礎となる構造は赤黒のツリーであるため、同じ要素がコンテナーに表示されないため、count() の結果は 0 と 1 しかありません。キー値要素が存在するかどうかを判断するために使用されます (もちろん、キーが存在するかどうかを判断するために find() メソッドを使用することもできます)。

class Solution {
    
    
public:
    vector<int> twoSum(vector<int>& nums, int target) {
    
    
    unordered_map<int,int> p;
    vector<int> an(2,-1); //返回答案,默认(-1,-1)
    for(int i = 0; i < nums.size();i++){
    
    
        if(p.count(target - nums[i])>0)
        {
    
    
            an[0] = i;
            an[1] = p[target - nums[i]];
            break;
        }
       p[nums[i]] = i;
    }
    return an;
    }
};

1.1 関連する知識ポイント:

map の利用と最適化 map の最下層は順序付けられた赤黒木であるため、要素を挿入するたびに回転やソートなどの操作を行う必要があり、時間がかかるため、最適化には unordered_map を使用できます。

2. 3 つの数値の合計

アイデア: 目標は、配列内で a + b + c = 0 を満たす 3 つの数値を見つけることであり、重複した回答を出力しないことです。まず、下付き文字ではなく特定の数字を出力するので、並べ替えることができます。

sort(nums.begin(),nums.end());//排序

並べ替えの後、最初に特別な判断について考えることができます。どのような配列出力が空ですか?
最初のタイプ: 順序付けられた配列の最初の要素が 0 より大きい、空を返す
2 番目のタイプ: 順序付けられた配列の最後の要素がまだ 0 より小さい、空を返す
3 番目のタイプ: すべての配列要素が 0 である、答えを返す第 4
タイプ: 配列要素の数が 3 未満の場合、空を返します

if(nums.size() < 3 || nums[0] > 0 || nums[n-1] < 0) return ans; //剪枝
if(!nums[0] && !nums[n-1]) return {
    
    {
    
    0, 0, 0}}; // 如果数组全为0

残りは、トラバースする必要がある配列です. 3 つの数値をトラバースして、a + b + c = 0 を満たすにはどうすればよいでしょうか? 3 層の for ループでは、最初の配列 a、次に 2 番目の配列が固定されています。数 b は、配列内の条件を満たす c をトラバースし、新しい数 b を修正し、再び c を見つけ、再び a を修正する、というように続きます。

考えてみてください: 条件付きでトラバースできるか、数を固定します。a、b は順序付けられた配列の前から後ろにトラバースし、c は順序付けられた配列の後ろから前にトラバースします。a + b + c が条件を満たさない場合、a + b + c > 0 または a + b + c < 0 の 2 つの場合があります。
次に、a + b + c > 0 は、c が大きすぎるために発生する必要があります。c を移動して前方にトラバースします。
次に、a + b + c < 0 は、b が小さすぎるために発生する必要があります。b を移動して後方にトラバースします。

for( i = 0 ; i < n - 2; ++i){
    
    
            if( i && nums[i]==nums[i-1]) continue; //消除重复的三元组
            j = i + 1;
            k = n - 1;
            while( j < k){
    
    
                int target = nums[i] + nums[j] + nums[k]; //避免下面加法运算两次
                if(target > 0) --k;       //因为nums已经有序,当target > 0; 说明k太大
                else if (target < 0) ++j; //因为nums已经有序,当target < 0; 说明j太大
                else{
    
    
                    ans.push_back({
    
    nums[i], nums[j], nums[k]}); //target ==0 输出答案
                    ++j;  // i 不变,j增加,k减小。不能同时固定两个数字,一定不满足要求(有序)
                    --k;
                    while(j < k &&nums[j] == nums[j-1]) ++j; // 有序数组,第二个数字不能相同
                    while(j < k && nums[k] == nums[k+1]) --k; //同理
                } 
            }
        }

コードをまとめる:

class Solution {
    
    
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
    
    
        vector<vector <int>> ans;
        int n = nums.size();
        ans.reserve( n > 256 ? 256 : n); //预先分配空间,以减少 push_back内存不足的时候重新申请的时间
        int i, j, k ;
        sort(nums.begin(),nums.end());//排序
        if(nums.size() < 3 || nums[0] > 0 || nums[n-1] < 0) return ans; //剪枝
        if(!nums[0] && !nums[n-1]) return {
    
    {
    
    0, 0, 0}}; // 如果数组全为0
        for( i = 0 ; i < n - 2; ++i){
    
    
            if( i && nums[i]==nums[i-1]) continue; //消除重复的三元组
            j = i + 1;
            k = n - 1;
            while( j < k){
    
    
                int target = nums[i] + nums[j] + nums[k]; //避免下面加法运算两次
                if(target > 0) --k;       //因为nums已经有序,当target > 0; 说明k太大
                else if (target < 0) ++j; //因为nums已经有序,当target < 0; 说明j太大
                else{
    
    
                    ans.push_back({
    
    nums[i], nums[j], nums[k]}); //target ==0 输出答案
                    ++j;  // i 不变,j增加,k减小。不能同时固定两个数字,一定不满足要求(有序)
                    --k;
                    while(j < k &&nums[j] == nums[j-1]) ++j; // 有序数组,第二个数字不能相同
                    while(j < k && nums[k] == nums[k+1]) --k; //同理
                } 
            }
        }

        return ans;
    }
};

2.1 関連スキル

ans.reserve( n > 256 ? 256 : n); //预先分配空间,以减少 push_back内存不足的时候重新申请的时间
 int i, j, k ;//不要加到循环中,不然每次都要申请会占用运行时间

おすすめ

転載: blog.csdn.net/qq_42573052/article/details/124148108