元素和是K的倍數的子串的最大長度

/***********************************************************************
 * 元素和是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;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章