LeetCode C++ 560. Subaray Sum Equals K【配列/ハッシュテーブル/接頭辞和】中等
Given an array of integers and an integer k k k , you need to find the total number of continuous subarrays whose sum equals to k k k .
Example 1:
Constraints: The length of the array is in range The range of numbers in the array is
題意:要素とk k kに等しい連続サブ配列の個数を探し出す.
構想1:各サブ配列を検索し、それらの和を計算します.
コードは次のとおりです.時間の制限を超えています.
考え方2:O(N)text{O(N)}O(N)まで時間の複雑さを低減するために,考えてみる必要がある.我々の目的は,和
我々は、遍歴群
コード:
効率:
Example 1:
Input:nums = [1,1,1], k = 2
Output: 2
Constraints:
[1, 20,000]
. [-1000, 1000]
and the range of the integer k
is [-1e7, 1e7]
. 題意:要素とk k kに等しい連続サブ配列の個数を探し出す.
構想1:各サブ配列を検索し、それらの和を計算します.
コードは次のとおりです.時間の制限を超えています.
class Solution {
public:
int subarraySum(vector<int>& nums, int k) {
int num = 0;
for (int i = 0; i < nums.size(); ++i) {
int sum = 0;
for (int j = i; j < nums.size(); ++j) {
sum += nums[j];
if (sum == k) ++num;
}
}
return num;
}
};
考え方2:O(N)text{O(N)}O(N)まで時間の複雑さを低減するために,考えてみる必要がある.我々の目的は,和
k
の連続サブ配列の個数を求めることである.区間和をいかに素早く求めるか――接頭辞とsum(nums[i:j]) = sum(nums[:j]) - sum(nums[:i])
!しかし、どのように題意と結びついているのでしょうか.我々は普段プレフィックス和を用いているが,連続区間[i, j]
の和を求めるために,これをk
と仮定すると,sum(nums[:j]) - sum(nums[i:j]) = sum(nums[:j]) - k = sum(nums[:i])
という公式が成り立つ.我々は、遍歴群
nums
を用いて、最初の要素から現在の要素までの和を計算し、ハッシュテーブルを用いて累積和sum
の出現回数を格納する.現在sum(nums[:j])
の値があり、前のすべての積算和sum(nums[:i])
が同時に記憶されているが、nums[0:j]
については、この区間内に和sum(nums[0:j]) - k = sum(nums[:i])
のサブ配列が存在する場合、和k
のサブ配列が存在することを示し、現在の下付きj
より前に連続するサブ配列の和がk
である.和k
のサブ配列の個数にはsum(nums[:i])
ハッシュテーブルでの出現回数を加算する必要がある.コード:
class Solution {
public:
int subarraySum(vector<int>& nums, int k) {
int num = 0, sum = 0;
unordered_map<int, int> dict;
dict[0] = 1;
for (int i = 0; i < nums.size(); ++i) {
sum += nums[i];
num += dict[sum - k];
++dict[sum];
}
return num;
}
};
効率:
:116 ms, C++ 55.37%
:26.5 MB, C++ 20.82%