2020-05-27 LeetCode 974 和可被 K 整除的子數組 C

題目:和可被 K 整除的子數組

 給定一個整數數組 A,返回其中元素之和可被 K 整除的(連續、非空)子數組的數目。

示例:

輸入:A = [4,5,0,-2,-3,1], K = 5
輸出:7
解釋:
有 7 個子數組滿足其元素之和可被 K = 5 整除:
[4, 5, 0, -2, -3, 1], [5], [5, 0], [5, 0, -2, -3], [0], [0, -2, -3], [-2, -3]

提示:

  1. 1 <= A.length <= 30000
  2. -10000 <= A[i] <= 10000
  3. 2 <= K <= 10000

 今天也是鬱悶,本來題目挺簡單的,自己瞎改測試用例用來debug廢了好多時,一直報內存泄漏的錯誤,最後發現是控制檯K給該沒了,大意。

 題目和560很像,思路是前綴和+同餘定理,用長度爲K的數組記錄即可,需要注意的是前綴和的餘數是負數的時候需要+K,遍歷過程中如果和的餘數爲0直接結果直接+1,其他則加同餘數的前綴和個數,第一版如下

int subarraysDivByK(int* A, int ASize, int K){

    int* const cnt=(int*)malloc(sizeof(int)*K);
    memset(cnt, 0, sizeof(int)*K);
    int i,ans=0,sum=0;
    for(i=0;i<ASize;i++){
        sum += A[i];
        sum = (sum % K + K) % K;
        if(sum==0)
            ans++;
        ans+=cnt[sum];
        cnt[sum]++;
    }
    free(cnt);
    return ans;
}

運行結果:
在這裏插入圖片描述

 後面進行了改進,把初始時候的cnt[0]置1就沒必要每次判斷和是否爲0了,改進後如下

int subarraysDivByK(int* A, int ASize, int K){
    int* const cnt = (int*)malloc(sizeof(int) * K);
    memset(cnt, 0, sizeof(int) * K);
    int i,ans=0,sum=0;
    cnt[0]=1;
    for(i=0;i<ASize;i++){
        sum += A[i];
        sum = (sum % K + K) % K;
        ans+=cnt[sum];
        cnt[sum]++;
    }
    free(cnt);
    return ans;
}

運行結果:

在這裏插入圖片描述
 個人感覺官方題解用HashMap的方式還可以優化,像560一樣如果能用數組表示的情況下用HashMap,雖然時間複雜度都是O(N),時間耗費肯定是會增加的。

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