* 元素和是K的倍數的子串的最大長度:
* 給定數組arr和整數K,求元素和是K的倍數的子串的最大長度
* 例:arr=[1,2,3,4,5] K=5
* 子串[5],[2,3],[1,2,3,4],[1,2,3,4,5]的和都是K的倍數
* 所以返回最大長度5
************************************************************************/
//思路:暴力法可以以O(N^2)的時間複雜度求解,考慮更優的解法
// 假設N>M,如果(arr[0]+...+arr[M])%K等於(arr[0]+...+arr[N])%K
// 則(arr[M+1]+...+arr[N])%K肯定等於0
// 所以對於arr[k],前k項和的餘數爲:(arr[0]+...+arr[k])%K
// arr[k]與第一次等於這個餘數的元素arr[i]之間的子串就是滿足要求的
// 求取最大長度即可。但數組前應添加一個0元素,否則第一個元素進不到求取範圍
#include<iostream>
#include<vector>
using namespace std;
int maxLength(vector<int> arr, int N, int K)
{
int result = 0;
vector<int> fisrtAppear(K);//記錄不同餘數第一次出現的索引
for (int i = 0; i < K; i++)
fisrtAppear[i] = -1;
fisrtAppear[0] = 0;
int mod = 0;
for (int i = 0; i < N; i++)
{
mod = (mod + arr[i]) % K;
if (fisrtAppear[mod] == -1)
fisrtAppear[mod] = i+1;
else
result = result < (i+1 - fisrtAppear[mod]) ? (i+1 - fisrtAppear[mod]) : result;
}
return result;
}
int main()
{
int N = 5;
vector<int> arr(N);
for (int i = 0; i < N; i++)
arr[i] = i+1;
int K = 5;
cout << maxLength(arr, N, K);
return 0;
}