記事ディレクトリ
1. 974. K で割り切れる部分配列の合計
1. トピックの紹介
974. K で割り切れるサブ配列の
合計 整数配列 nums と整数 k を指定すると、要素の合計が k で割り切れる (連続した空でない) サブ配列の数を返します (サブ配列は配列の連続部分です)。
2. 問題解決のアイデア
3.コード
class Solution {
public:
int subarraysDivByK(vector<int>& nums, int k) {
//(sum[i] - sum[x]) % k == 0 => sum[i] % k == sum[x] % k;
unordered_map<int, int> ma;//存储至今为止的前缀和对k取余的结果出现的次数
ma[0 % k] = 1;
int sum = 0;
int ret = 0;
for(int i = 0;i < nums.size(); ++i)
{
sum += nums[i];
int t = (sum % k + k) % k;//修正负数取模的结果。C++对负数的取模机制会导致结果出错(先去掉负数的符号,然后将它当中一个正数进行取模,最后再带上符号)
if(ma.count(t)) ret += ma[t];
ma[t]++;
}
return ret;
}
};
4. 走行結果
2. 525. 連続配列
1. トピックの紹介
525. 連続配列
バイナリ配列 nums を指定して、同じ数の 0 と 1 を含む最長の連続した部分配列を見つけて、その部分配列の長さを返します。
2. 問題解決のアイデア
3.コード
class Solution {
public:
int findMaxLength(vector<int>& nums) {
map<int, int> ma;//存放至今为止出现的前缀和以及第一次出现该sum的下标
ma[0] = -1;//默认有一个前缀和为0的情况
for(auto& e : nums)
{
if(e == 0) e = -1;
}
//将数组中的0转化为-1,这样问题就转变为和为0的最长连续子数组,推测为找和为sum的最短连续子数组
int sum = 0;
int ret = 0;
for(int i = 0;i < nums.size(); ++i)
{
sum += nums[i];
if(ma.count(sum))
{
ret = max(ret, i - ma[sum]);
}
else
ma[sum] = i;
}
return ret;
}
};
4. 走行結果
3. 560. 和が K である部分配列
1. トピックの紹介
560. 合計が K である部分配列。
整数配列 nums と整数 k が与えられます。合計が k である配列内の連続する部分配列の数を数えて返してください。
2. 問題解決のアイデア
3.コード
class Solution {
public:
int subarraySum(vector<int>& nums, int k) {
unordered_map<int, int> ma;//至今为止前缀和出现的次数
ma[0] = 1;//初始化(前缀和正好等于k的情况)
int ret = 0;
int sum = 0;//前缀和
for(int i = 0;i < nums.size(); ++i)
{
sum += nums[i];
int t = sum - k;
if(ma.count(t)) ret += ma[t];
ma[sum]++;
}
return ret;
}
};
4. 走行結果
要約する
今日はアルゴリズム実習8日目です。
したがって、過去の人々を戒めなければ、これから何が起こるかを知っている人々を追いかけることができます。決して諦めずに良い仕事を続けてください。
この記事があなたにインスピレーションを与えたなら、著者をもっとサポートしていただければ幸いです。皆さん、ありがとう!