질문 출처 : https://leetcode-cn.com/problems/continuous-subarray-sum/
제목 설명
음수가 아닌 숫자와 대상 정수 k를 포함하는 배열이 주어지면 배열에 크기가 2 이상이고 합이 k의 배수 인 연속 하위 배열이 포함되어 있는지 여부를 확인하는 함수를 작성합니다. sum은 n * k입니다. 여기서 n은 정수이기도합니다.
示例 1:
输入:[23,2,4,6,7], k = 6
输出:True
解释:[2,4] 是一个大小为 2 的子数组,并且和为 6。
示例 2:
输入:[23,2,6,4,7], k = 6
输出:True
解释:[23,2,6,4,7]是大小为 5 的子数组,并且和为 42。
说明:
数组的长度不会超过 10,000 。
你可以认为所有数字总和在 32 位有符号整数范围内。
일반적인 생각
- 배열이 주어지면 길이가 2보다 큰 연속 하위 배열의 합이 n * k인지 확인하고 True와 False를 반환합니다.
접두사 및 + 폭력적 열거
- 연속 하위 배열의 합은 접두사 합계를 사용하여 간격의 합계 처리 시간 복잡성을 최적화 할 수 있습니다. 무차별 대입 열거는 다음 조건을 충족하는 배열을 찾습니다
(합계 [j]-합계 [i-1]). % k = 0 (sums [j] -sum [i-1]) \ % k = 0( s u m s [ j ]−s u m [ i−1 ] ) % k=0
class Solution {
public:
bool checkSubarraySum(vector<int>& nums, int k) {
int len = nums.size();
int sums[len + 1];
memset(sums, 0, sizeof(sums));
for(int i = 1; i <= len ; ++i) sums[i] = sums[i - 1] + nums[i - 1];
for(int i = 1 ; i <= len ; ++i){
for(int j = i + 1 ; j <= len ; ++j){
if(k == 0 && sums[j] - sums[i - 1] == 0) return true;
if(k != 0 && (sums[j] - sums[i - 1]) % k == 0) return true;
}
}
return false;
}
};
복잡성 분석
- 시간 복잡도 : O (n ^ 2). n은 배열의 길이입니다.
- 공간 복잡성 : O (ln). n은 배열의 길이입니다.
HashMap + 접두사 합계
- 공식을 더 단순화 할 수 있습니다. 동일한 접두사와 동일한 값이 동일한 값에 매핑됩니다. 여기서 접두사와 합계 [0]도 매핑해야합니다. k = 0
(합계 [ j] − sum [i − 1]) (mod) k = 0 → sums [j] (mod) k ⟺ sum [i − 1] (mod) k (sums [j] -sum [i-1]) ( mod) k = 0 → sums [j] (mod) k⟺sum [i-1] (mod) k( s u m s [ j ]−s u m [ i−1 ] ) ( m o d ) k=0→s u m s [ j ] ( m o d ) k⟺s u m [ i−1 ] ( m o d ) k
class Solution {
public:
bool checkSubarraySum(vector<int>& nums, int k) {
int len = nums.size();
int sums[len + 1];
memset(sums, 0, sizeof(sums));
map<int, vector<int>> mmap;
if(k == 0){
for(int i = 0 ; i < len - 1; ++i){
if(nums[i + 1] == nums[i] && nums[i] == 0) return true;
}
return false;
}
for(int i = 1; i <= len ; ++i){
sums[i] = sums[i - 1] + nums[i - 1];
mmap[sums[i] % k].push_back(i);
}
// sums[0] -> 0 -> index : 0
// sums[1] -> nums[0] -> index : 0
mmap[0].push_back(0);
for(int i = 1 ; i <= len ; ++i){
int index = sums[i] % k;
for(auto it : mmap[index]){
// 排除长度为1
if (i - 1 > it) return true;
}
}
return false;
}
};
복잡성 분석
- 시간 복잡도 : O (n). n은 배열의 길이이고 해당 액세스 매핑 배열의 평균 복잡도는 O (1)입니다.
- 공간 복잡성 : O (n). 무순 맵의 길이는 최대 배열 길이입니다.