Ant Design Blazor 元件庫的路由複用多標籤頁功能
阿新 • • 發佈:2021-07-09
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);
體會
連續子陣列+和 --> 字首和;