⭐算法入门⭐《前缀和》中等02 —— LeetCode 974. 和可被 K 整除的子数组

Posted 英雄哪里出来

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了⭐算法入门⭐《前缀和》中等02 —— LeetCode 974. 和可被 K 整除的子数组相关的知识,希望对你有一定的参考价值。

🔥让天下没有难学的算法🔥

C语言免费动漫教程,和我一起打卡!
🌞《光天化日学C语言》🌞

入门级C语言真题汇总
🧡《C语言入门100例》🧡

几张动图学会一种数据结构
🌳《画解数据结构》🌳

组团学习,抱团生长
🌌《算法入门指引》🌌

竞赛选手金典图文教程
💜《夜深人静写算法》💜

一、题目

1、题目描述

  给定一个整数数组 A,返回其中元素之和可被 K 整除的(连续、非空)子数组的数目。
  样例输入: A = [4,5,0,-2,-3,1], K = 5
  样例输出: 7

2、基础框架

  • C语言 版本给出的基础框架代码如下:
int subarraysDivByK(int* nums, int numsSize, int k){
}

3、原题链接

LeetCode 974. 和可被 K 整除的子数组

二、解题报告

1、思路分析

1)初始化前缀和

  首先,一遍线性枚举,计算前缀和 s u m [ i ] = ∑ j = 0 i n u m s [ i ] sum[i] = \\sum_{j=0}^inums[i] sum[i]=j=0inums[i]
  然后,对于某个非空子数组nums[i:j],如果它能够被 k k k 整除,则必然有:
( s u m [ j ] − s u m [ i − 1 ] )   m o d   k = = 0 (sum[j] - sum[i-1]) \\ mod \\ k == 0 (sum[j]sum[i1]) mod k==0  即对于每个 ( 0 ≤ i ≤ j < n ) (0 \\le i \\le j \\lt n) (0ij<n), 满足 s u m [ i − 1 ]   m o d   k = = s u m [ j ]   m o d   k sum[i-1] \\ mod \\ k == sum[j] \\ mod \\ k sum[i1] mod k==sum[j] mod k

2)哈希表统计

  利用一个哈希表 h h h,初始情况插入一个 s u m [ − 1 ] sum[-1] sum[1],也就是 0;
  然后遍历 i = 0 → n − 1 i = 0 \\to n-1 i=0n1,询问 哈希表中 s u m [ i ] sum[i] sum[i] 的值累加到结果 a n s ans ans 中,并且将 s u m [ i ] sum[i] sum[i] 继续插入哈希表。结果返回 a n s ans ans 即可。

2、时间复杂度

  • 前缀和初始化,只需要一次遍历,时间复杂度为 O ( n ) O(n) O(n)
  • 哈希统计过程,只需要遍历一遍数组,也是 O ( n ) O(n) O(n)

3、代码详解

#define maxn 30003
int sum[maxn], h[maxn];

int subarraysDivByK(int* nums, int numsSize, int k){
    int i;
    int ans = 0;
    for(i = 0; i < numsSize; ++i) {
        sum[i] = nums[i] % k;
        if(i) {
            sum[i] = (sum[i] + sum[i-1]) % k;   // (1) 
        }
        if(sum[i] < 0) {
            sum[i] += k;                        // (2) 
        }
    }
    memset(h, 0, sizeof(h));
    h[0] = 1;                                   // (3)
    for(i = 0; i < numsSize; ++i) {
        ans += h[ sum[i] ];                     // (4)
        ++h[ sum[i] ];                          // (5)
    }
    return ans;
}

  • ( 1 ) (1) (1) 计算前缀和模 k k k
  • ( 2 ) (2) (2) 确保每个sum[i]都是大于等于 0 0 0 的;
  • ( 3 ) (3) (3) 初始化哈希表,并且插入第一个元素 s u m [ − 1 ] sum[-1] sum[1]
  • ( 4 ) (4) (4) 累加哈希表中 s u m [ i ] sum[i] sum[i] 的值;
  • ( 5 ) (5) (5) s u m [ i ] sum[i] sum[i] 插入到哈希表;

三、本题小知识

前缀和的问题,一般是先初始化前缀和,然后再进行一次线性枚举,通过 O ( 1 ) O(1) O(1) 的时间取前缀和的结果。


以上是关于⭐算法入门⭐《前缀和》中等02 —— LeetCode 974. 和可被 K 整除的子数组的主要内容,如果未能解决你的问题,请参考以下文章

⭐算法入门⭐《链表》中等02 —— LeetCode 143. 重排链表

⭐算法入门⭐《二分枚举》中等02 —— LeetCode 面试题 10.09. 排序矩阵查找

⭐算法入门⭐《线性枚举》中等02 —— LeetCode 628. 三个数的最大乘积

⭐算法入门⭐《哈希表》中等02 —— LeetCode 560. 和为K的子数组

解题报告力扣 第 280 场周赛

⭐算法入门⭐《堆》中等02 —— LeetCode 703. 数据流中的第 K 大元素