[Leetcode] YuanChuが選択した質問の詳細な説明とKの合計のサブ配列

タイトルの説明:560合計はKのサブ配列です

整数配列と整数kが与えられた場合、配列内で合計がkになる連続するサブ配列の数を見つける必要があります。

例1:

输入:nums = [1,1,1], k = 2
输出: 2 

説明:[1,1]と[1,1]は2つの異なる状況です。

例2:

输入:nums = [1,1,1,0], k = 2
输出: 3 

説明:[1,1]、[1,1]、[1,1,0]はすべて

例3:

输入:nums = [-1,1,1,0], k = 2
输出: 2

説明:[1,1]、[1,1,0]は両方とも

主題の要件は十分に理解されていますが、int型の配列であるため、最初に発生するすべての状況を考慮する必要があります。したがって、内部の整数型は0以上、0に等しく、0より大きいです。したがって、このトピックを実行するときは、配列に0が含まれている場合の状況を考慮する必要があります。たとえば、例2では、​​[1,1]、[1,1,0]はすべてサブ配列であり、これを省略できません。ハプニング。質問をブラッシングし始めたばかりの学生の中には、この状況を考えていない人もいるかもしれません。元の質問の例では1つの例しか示されていないため、特別な状況は考えられませんが、ブラッシングする質問の数が増えると、質問を分析する能力が向上します。強くなればなるほど、質問を受けたときに最初にいくつかの特別な例を考えることができます。

まず、暴力的な解決策について話しましょう

注:暴力的な方法は簡単に考えることができますが、暴力的な方法の時間の複雑さは比較的高くなる傾向があります。時間の複雑さは比較的高いですが、暴力的な解決策を無視してはなりません(特にわからない問題が発生した場合)。多くの場合、他の解決策は暴力的な方法の最適化です。したがって、問題を解決するとき、私たちは優れているべきではなく、暴力的な方法を無視する必要があります。代わりに、ブルートフォースメソッドを最適化してみてください。

ブルートフォース法の考え方は非常に単純で、二重ループであり、nums [j]を累積し、合計がK値の場合、カウンターは1増加します。トラバーサルが終了すると、値が返されます。ブルートフォース法は、0が存在する状況にも適用できます。合計+ 0であるため、値はまだ合計です。この時点で合計がkに等しい場合、カウンターは1つ増えます。

ここに写真の説明を挿入

質問コード:

class Solution {
    
    
    public int subarraySum(int[] nums, int k) {
    
    
          if(nums.length == 0){
    
    
              return 0;
          }  
          //计数器
          int count = 0;
          //代表的是蓝指针的运动轨迹
          for(int i =0;i<nums.length;i++){
    
    
              int sum = 0;
              //代表橙指针的运动轨迹
              for(int j =i;j<nums.length;j++){
    
    
                  //将橙指针遍历的值进行相加
                  sum += nums[j];
                  //等于时计数器加1
                  if(sum == k){
    
    
                      count++;
                      //这里不可以break,因为可能有这种情况k=1数组为[1,0,0,1,-1]这个情况
                  }                  
              }
          }
          return count;
    }
}

ハッシュマップ法:

この方法はもっと巧妙です。Leetcodeにはこの方法を使用できる質問がいくつかあるので、読者がこの方法を詳しく見てくれることを願っています。質問の最初は少し難しいように思われるかもしれませんが、一緒に話し合うことができます。

合計値の変化を見てみましょう

sum [0] = nums [0];

sum [1] = nums [0] + nums [1];

sum [2] = nums [0] + nums [1] + nums [2];

sum [3] = nums [0] + nums [1] + nums [2] + nums [3];

sum [3] = sum [2] + nums [3]であるため、sum [3] -sum [2] = nums [3]、sum [3] -sum [1] = nums [2] + nums [3 ];

上記の式から、sum [j] -sum [i] = kであり、変換はsum [j] -k = sum [i]であることがわかります。この問題は、sum [i]の出現数になっています。

ここに写真の説明を挿入

ここに写真の説明を挿入

class Solution {
    
           
    public int subarraySum(int[] nums, int k) {
    
    
        int count = 0;//计数器
        if(nums.length < 1){
    
    
            return 0;
        }
        //hashmap用来存sum[i]的和出现的次数
        HashMap<Integer, Integer> map = new HashMap<>();
        map.put(0,1);//防止这种情况,数组只有一个1,k=1则count=1
        int sum = 0;
        for(int i = 0; i<nums.length; i++){
    
    
           sum += nums[i];//累加
            //获取sum-k出现的个数,例当前指针在第j位。sum[j]=10,k=2,
            //则需要知道sum[i]=8时,共有几种情况,sum[i]代表的是前i位的值
           if(map.containsKey(sum - k)){
    
    
               count += map.get(sum-k);//获取次数
           }
           map.put(sum,map.getOrDefault(sum,0)+1);//没出现则存入一次
       }
       return count;
    }
    
}

おすすめ

転載: blog.csdn.net/tan45du_yuan/article/details/109297850