アルゴリズム-合計がKのサブアレイ
1.合計がKであるサブアレイ
给定一个整数数组和一个整数 k,你需要找到该数组中和为 k 的连续的子数组的个数。
示例 1 :
输入:nums = [1,1,1], k = 2
输出: 2 , [1,1] 与 [1,1] 为两种不同的情况。
说明 :
数组的长度为 [1, 20,000]。
数组中元素的范围是 [-1000, 1000] ,且整数 k 的范围是 [-1e7, 1e7]。
この質問はバイトインタビューの質問であり、Leetcodeの中レベルの質問でもあります。質問の目的も明らかで、合計がKである連続したシーケンスの数を見つけることです。ただし、この質問では、番号が乱れている可能性があります。これは、Jianzhiが提供するような数学ではもはや実行できません。
もちろん、この問題には暴力的な解決策があり、時間の複雑さはO(N)です。主なアイデアは、2つのポインターを宣言することです。1つは連続シーケンスの開始位置を指し、もう1つは連続シーケンスの終了を指します。この問題は、2レベルのトラバーサルを使用して解決できます。この方法は比較的単純ですが、時間の複雑さはO(N ^ 2)です。テストケースに合格することはできますが、数百ミリ秒かかります。pythonなどの言語に変更すると確実にタイムアウトになります。
public int subarraySum(int[] nums, int k) {
int slow=0,quick=0;
int tempK=k;
int count=0;
while(slow<nums.length){
if(quick==nums.length){
tempK=k;
quick=++slow;
}else if(tempK-nums[quick]==0){
count++;
tempK-=nums[quick++];
}else{
tempK-=nums[quick++];
}
}
return count;
}
ハッシュテーブルを使用して別のソリューションを実現できます。Leetcodeの最初の質問を覚えていますか?2つの合計の問題には、HashMapを使用したO(N)ソリューションがあります。このトピックの考え方はそれと一致しています。
ハッシュマップを使用して、同じ合計の発生数を格納します。現在の合計がターゲットの合計と等しくなると、現在の適格なシリーズの数+1になります。sum-kが含まれている場合、sum-kと現在の要素のm個のサブシーケンスの合計は次のようになります。連続シーケンスを形成するため、現在の連続サブシーケンスの数をmに追加する必要があります。最後に、各合計の発生数を記録します。
public int subarraySum(int[] nums, int k) {
int sum=0,count=0;
Map<Integer,Integer> map=new HashMap<>();
for (int i=0;i<nums.length;i++){
sum+=nums[i];
if(sum==k){
count++;
}
if(map.containsKey(sum-k)){
count+=map.get(sum-k);
}
if(!map.containsKey(sum)){
map.put(sum,1);
}else {
map.put(sum,map.get(sum)+1);
}
}
return count;
}
コードは比較的明確に書かれていますが、より多くの解釈があります。