Получен целочисленный массив nums
и целое число k
Верните true
, если у nums
есть хороший подмассив, или false
в противном случае.
Хороший подмассив – это подмассив, у которого:
длина равна по меньшей мере двум,
сумма элементов подмассива кратна k
.
Обратите внимание, что:
Подмассив – это непрерывная часть массива.
Целое число x
кратно k
, если существует целое число n
такое, что x = n * k
.
0
всегда кратно k
.
Входные данные: nums = [23,2,4,6,7], k = 6
Результат: true
Объяснение: [2, 4] представляет собой непрерывный подмассив размера 2
, элементы которого в сумме составляют 6
.
Входные данные: nums = [23,2,6,4,7], k = 6
Результат: true
Объяснение: [23, 2, 6, 4, 7] представляет собой непрерывный подмассив размера 5, сумма элементов которого составляет 42. 42 кратно 6, потому что 42 = 7 * 6, а 7 - целое число.
Входные данные: nums = [23,2,6,4,7], k = 13
Результат: false
class Solution {
public:
bool checkSubarraySum(vector<int>& nums, int k) {
unordered_map<int,int>m;
m[0] = -1;
int sum = 0, len = nums.size();
if(k == 0) return false;
for(int i = 0; i < len; i++) {
sum += nums[i];
if(k != 0) {
sum %= k;
}
if(m.count(sum) == 0) {
// такого остатка от деления не было
// запоминаем индекс, на котором он встретился
m[sum] = i;
} else {
// такой остаток уже встречался,
// это кандидат на успешно найденную последовательность
// нужно проверить, чтобы разность текущего и ранее встреченного индексов
// была больше единицы (в последовательности два элемента и больше)
if(i - m[sum] > 1) return true;
}
}
return false;
}
};
Элементы массива nums
последовательно складываются, сумма делится на k
, определяется остаток от деления.
В карте m
запоминаются индексы, в которых встречался соответствующий остаток от деления.
Если данный остаток от деления (sum
) встретится ещё раз, то между текущим положением элемента (i
) и прежним положением (m[sum]
) даст последовательность, которая нацело делится на k
.
Например,