Given a list of non-negative numbers and a target integer k, write a function to check if the array has a continuous subarray of size at least 2 that sums up to the multiple of k, that is, sums up to n*k where n is also an integer.

Example 1:

Input: [23, 2, 4, 6, 7],  k=6
Output: True
Explanation: Because [2, 4] is a continuous subarray of size 2 and sums up to 6.

Example 2:

Input: [23, 2, 6, 4, 7],  k=6
Output: True
Explanation: Because [23, 2, 6, 4, 7] is an continuous subarray of size 5 and sums up to 42.

Note:

    1. The length of the array won't exceed 10,000.
    2. You may assume the sum of all the numbers is in the range of a signed 32-bit integer.

这道题给了我们一个数组和一个数字k,让我们求是否存在这样的一个连续的子数组,该子数组的数组之和可以整除k。遇到除法问题,我们肯定不能忘了除数为0的情况等处理。还有就是我们如何能快速的遍历所有的子数组,并且求和,我们肯定不能完全的暴力破解,这样OJ肯定不答应。我们需要适当的优化,如果是刷题老司机的话,遇到这种求子数组或者子矩阵之和的题,应该不难想到要建立累加和数组或者累加和矩阵来做。没错,这道题也得这么做,我们要遍历所有的子数组,然后利用累加和来快速求和。在得到每个子数组之和时,我们先和k比较,如果相同直接返回true,否则再判断,若k不为0,且sum能整除k,同样返回true,最后遍历结束返回false,参见代码如下:

解法一:

class Solution {
public:
bool checkSubarraySum(vector<int>& nums, int k) {
for (int i = ; i < nums.size(); ++i) {
int sum = nums[i];
for (int j = i + ; j < nums.size(); ++j) {
sum += nums[j];
if (sum == k) return true;
if (k != && sum % k == ) return true;
}
}
return false;
}
};

下面这种方法用了些技巧,那就是,若数字a和b分别除以数字c,若得到的余数相同,那么(a-b)必定能够整除c。这里就不证明了,博主也不会证明。明白了这条定理,那么我们用一个集合set来保存所有出现过的余数,如果当前的累加和除以k得到的余数在set中已经存在了,那么说明之前必定有一段子数组和可以整除k。需要注意的是k为0的情况,由于无法取余,我们就把当前累加和放入set中。还有就是题目要求子数组至少需要两个数字,那么我们需要一个变量pre来记录之前的和,我们每次存入set中的是pre,而不是当前的累积和,参见代码如下:

解法二:

class Solution {
public:
bool checkSubarraySum(vector<int>& nums, int k) {
int n = nums.size(), sum = , pre = ;
unordered_set<int> st;
for (int i = ; i < n; ++i) {
sum += nums[i];
int t = (k == ) ? sum : (sum % k);
if (st.count(t)) return true;
st.insert(pre);
pre = t;
}
return false;
}
};

既然set可以做,一般来说用哈希表也可以做,这里我们建立余数和当前位置之间的映射,由于有了位置信息,我们就不需要pre变量了,之前用保存的坐标和当前位置i比较判断就可以了,参见代码如下:

解法三:

class Solution {
public:
bool checkSubarraySum(vector<int>& nums, int k) {
int n = nums.size(), sum = ;
unordered_map<int, int> m{{,-}};
for (int i = ; i < n; ++i) {
sum += nums[i];
int t = (k == ) ? sum : (sum % k);
if (m.count(t)) {
if (i - m[t] > ) return true;
} else m[t] = i;
}
return false;
}
};

参考资料:

https://discuss.leetcode.com/topic/80975/java-solution

https://discuss.leetcode.com/topic/80793/java-o-n-time-o-k-space/2

https://discuss.leetcode.com/topic/80892/concise-c-solution-use-set-instead-of-map

LeetCode All in One 题目讲解汇总(持续更新中...)

[LeetCode] Continuous Subarray Sum 连续的子数组之和的更多相关文章

  1. [LeetCode] 560. Subarray Sum Equals K 子数组和为K

    Given an array of integers and an integer k, you need to find the total number of continuous subarra ...

  2. LeetCode 209. Minimum Size Subarray Sum (最短子数组之和)

    Given an array of n positive integers and a positive integer s, find the minimal length of a contigu ...

  3. [LeetCode] Subarray Sum Equals K 子数组和为K

    Given an array of integers and an integer k, you need to find the total number of continuous subarra ...

  4. [leetcode]523. Continuous Subarray Sum连续子数组和(为K的倍数)

    Given a list of non-negative numbers and a target integer k, write a function to check if the array ...

  5. [LintCode] Continuous Subarray Sum 连续子数组之和

    Given an integer array, find a continuous subarray where the sum of numbers is the biggest. Your cod ...

  6. lintcode :continuous subarray sum 连续子数组之和

    题目 连续子数组求和 给定一个整数数组,请找出一个连续子数组,使得该子数组的和最大.输出答案时,请分别返回第一个数字和最后一个数字的值.(如果两个相同的答案,请返回其中任意一个) 样例 给定 [-3, ...

  7. LeetCode Continuous Subarray Sum 题解 同余前缀和 Hash表

    文章目录 题意 思路 特殊情况k=0 Source Code 1 Source Code 2 题意 给定一个数组和一个整数k,返回是否存在一个长度至少为2的连续子数组的和为k的倍数. 思路 和上一篇博 ...

  8. LeetCode Continuous Subarray Sum

    原题链接在这里:https://leetcode.com/problems/continuous-subarray-sum/description/ 题目: Given a list of non-n ...

  9. 523. Continuous Subarray Sum

    class Solution { public: bool checkSubarraySum(vector<int>& nums, int k) { unordered_map&l ...

随机推荐

  1. 转载:lua中switch

    刚开始使用lua的人肯定会不满lua居然没有switch这个语法. 但是熟悉lua的强大特性之后,你会发现其实switch是完全没有必要提供的^.^,因为lua有强大的table和function 例 ...

  2. 【动态规划】记忆搜索(C++)

    前几天还在踟蹰我应该注重培养做项目的能力还是修炼算法以及数据结构,然后发现这个场景有点似曾相识.曾几何时的一个月里,我有三件比较重要的事情要解决,在那个月刚开始的时候我一直在想我应该从那件事情开始着手 ...

  3. C#编程语言之委托与事件(一)—— C/C++函数指针和C#委托初步

    相信正在学习C#的人都有学习过C或C++的经验,本文要讲的第一个要点是C#中的委托(delegate,有些资料也叫代表).什么是委托,很多人都能自然而然地想到C/C++中的函数指针,事实上很多书和资料 ...

  4. JS常见操作,日期操作,字符串操作,表单验证等

    复制代码 //第一篇博文,希望大家多多支持 /***** BasePage.js 公共的 脚本文件 部分方法需引用jquery库 *****/ //#region 日期操作 //字符串转化为时间. f ...

  5. ORA-03206,当表空间不够时,如何以添加数据文件的方式扩展表空间

    准备导入一个数据库,大约为33G,开始创建的空库表空间为自增到20G,结果自然不够,然后就开始自动扩展表空间大小 使用的如下语句 --自动扩展表空间大小 ALTER DATABASE DATAFILE ...

  6. C语言第三次博客作业—循环结构

    一.PTA实验作业 题目1 1.实验代码 int N,i; //N为用户数 char sex; //sex表示性别 double High; //Hight表示身高 scanf("%d&qu ...

  7. 利用python实现简单登陆注册系统

    #!/usr/bin/env python # -*- coding:utf-8 -*- def login(username,password): ''' :param username:用户名 : ...

  8. JAVA_SE基础——62.String类的构造方法

    下面我先列出初学者目前用到的构造方法 String 的构造方法:     String()  创建一个空内容 的字符串对象.   String(byte[] bytes)  使用一个字节数组构建一个字 ...

  9. Spring MVC拦截器的配置

    最近在用SpringMVC,想用它的拦截器,但是配置了几次都不成功了,最后翻阅了不少文章终于成功了,遂记录于此,以方便他人. 首先引入命名空间: xmlns:mvc="http://www. ...

  10. python爬虫requests 下载图片

    import requests # 这是一个图片的url url = 'http://yun.itheima.com/Upload/Images/20170614/594106ee6ace5.jpg' ...