1. 程式人生 > 程式設計 >Ant Design Blazor 元件庫的路由複用多標籤頁功能

Ant Design Blazor 元件庫的路由複用多標籤頁功能

974. 和可被 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]。

解法一:字首和

連續子陣列,又帶有和-->字首和;這和基礎裡的連續子陣列和為k有什麼區別呢,這個題元素之和可被k整除,前者我們很簡單,和為k,也就是找Sm-Sn=k;現在怎麼辦,變成了(Sm-Sn)%k=0,那轉化一下就變成了Sm%k=Sn%k;其實很好理解,如果兩個數除以某個數的餘數相等的話,那它們相減一定能整除k(餘數相減抵消了)。
注意題目中有一個細節:mod = (presum % k + k) % k;這樣寫而不是直接presum % k的原因是不同語言對帶有負數的取餘運算不一樣;如下圖; 餘數滿足這樣的定義:a = qd + r , q 為整數,且0 ≤ |r| < |d|很明顯兩個都滿足。這樣就得到了兩個餘數,一個正餘數r1,一個負餘數r2,兩者關係為:r1 = r2 + d;所以我們有了上面的操作。以後只要記住:在java、c++取餘數符號跟著被除數,在python等新型語言取餘數符號跟著除數。

class Solution {
    public int subarraysDivByK(int[] nums, int k) {
        Map<Integer,Integer> map = new HashMap<>();
        map.put(0,1);
        int count = 0;
        int presum = 0;
        for(int i = 0; i < nums.length; i++){
            presum += nums[i]; //字首和;
            int mod = (presum % k + k) % k;  //求餘數,如果兩個餘數相等,相減之後消去一定能整除;
            if(map.containsKey(mod)) count += map.get(mod);
            map.put(mod, map.getOrDefault(mod, 0)+1);
        }
        return count;
    }
}

時間複雜度:O(N);

體會

連續子陣列+和 --> 字首和;