523. Continuous Subarray Sum
来源:互联网 发布:centos 7 mysql 编辑:程序博客网 时间:2024/06/05 07:06
一、题目简述
给定一个非负数组和目标整数K,写一个函数以检测给定数组中是否有一个长度至少为2的连续子序列,使得其和能够被K整除,即,其和为
示例1
Input:
Output:
Explanation: Because
示例2
Input:
Output:
Explanation: Because
注意:
- The length of the array won’t exceed 10,000.
- You may assume the sum of all the numbers is in the range of a signed 32-bit integer.
函数原型: bool checkSubarraySum(vector<int>& nums, int k)
二、编程思路
思路一:暴力求解
每个子序列的起始下标与终止下标均在
该方法的时间复杂度为
思路二:动态规划
令
则有:
使用一个二维数组记录各个子序列之和,如下图所示。
该方法的时间复杂度为
根据题中所给条件,序列最长为10000,则需要申请10000*10000的二维数组,运行时会报
思路三:动态规划二
在思路二中,可以发现每次只需二维数组中一列的数据,因此没有必要将整个数组保留下来。因此只申请一个长度为10000的数组,在每次操作时对其进行更新。记录从s开始长度为l的序列之和。
该方法的时间复杂度为
思路四:
参考网上大神时间复杂度为
原理:
对于序列
则有:
对于本题,求出从序列nums从0开始到
该方法的时间复杂度为
三、程序设计
思路一:AC
class Solution {public: bool checkSubarraySum(vector<int>& nums, int k) { int size=nums.size(); if(!size) return false; int vsum = accumulate(nums.begin() , nums.end(),0); if(k==0 && vsum==0 && size>1) return true; if(k==0) return false; for(int i=0;i<size;i++){ int sum=nums[i]; for(int j=i+1;j<size;j++){ sum+=nums[j]; if(sum%k==0){ // cout<<i<<" "<<j<<endl; return true; } } } return false; }};
思路二:ME
#include<stdio.h>#include<stdlib.h>#include<string.h>#define MAX_SIZE 10000int sum[MAX_SIZE][MAX_SIZE]={-1};class Solution {public: bool checkSubarraySum(vector<int>& nums, int k) { //special condation int size=nums.size(); if(!size) return false; int vsum = accumulate(nums.begin() , nums.end(),0); if(k==0 && vsum==0 && size>1) return true; if(k==0) return false; //general condation memset(sum,0,sizeof(int)*MAX_SIZE*MAX_SIZE); for(int i=0;i<size;i++){ sum[i][0]=nums[i]; } for(int len=2;len<=size;len++){ for(int start=0;start<size;start++){ if(start+len-1>=size) continue; if(sum[start][len-1]<=0){ sum[start][len-1]=sum[start][len-2]+nums[start+len-1]; } if(sum[start][len-1]%k==0){ //cout<<start<<" "<<len<<endl; return true; } } } return false; }};
思路三:AC
#include<stdio.h>#include<stdlib.h>#include<string.h>#define MAX_SIZE 10000int sum[MAX_SIZE]={-1};class Solution {public: bool checkSubarraySum(vector<int>& nums, int k) { //special condation int size=nums.size(); if(!size) return false; int vsum = accumulate(nums.begin() , nums.end(),0); if(k==0 && vsum==0 && size>1) return true; if(k==0) return false; //general condation memset(sum,0,sizeof(int)*MAX_SIZE); for(int i=0;i<size;i++){ sum[i]=nums[i]; } for(int len=2;len<=size;len++){ for(int start=0;start<size;start++){ if(start+len-1>=size) continue; sum[start]=sum[start]+nums[start+len-1]; if(sum[start]%k==0){ return true; } } } return false; }};
思路四:AC
class Solution {public: bool checkSubarraySum(vector<int>& nums, int k) { map<int,int> m; map<int,int>::iterator it=m.end(); int sum=0; m[0]=-1; for(int i=0;i<nums.size();i++){ sum+=nums[i]; if(k) sum%=k; it=m.find(sum); if(it!=m.end()){ if(i-it->second > 1){ return true; } }else{ m[sum]=i; } } return false; }};
四、实验心得
动态规划在查找有很多重叠子问题的情况的最优解时有效。它将问题重新组合成子问题。为了避免多次解决这些子问题,它们的结果都逐渐被计算并被保存,从简单的问题直到整个问题都被解决。因此,动态规划保存递归时的结果,因而不会在解决同样的问题时花费时间。
动态规划只能应用于有最优子结构的问题。最优子结构的意思是局部最优解能决定全局最优解(对有些问题这个要求并不能完全满足,故有时需要引入一定的近似)。简单地说,问题能够分解成子问题来解决。
适用情况:
- 最优子结构性质。如果问题的最优解所包含的子问题的解也是最优的,我们就称该问题具有最优子结构性质(即满足最优化原理)。最优子结构性质为动态规划算法解决问题提供了重要线索。
- 无后效性。即子问题的解一旦确定,就不再改变,不受在这之后、包含它的更大的问题的求解决策影响。
- 子问题重叠性质。子问题重叠性质是指在用递归算法自顶向下对问题进行求解时,每次产生的子问题并不总是新问题,有些子问题会被重复计算多次。动态规划算法正是利用了这种子问题的重叠性质,对每一个子问题只计算一次,然后将其计算结果保存在一个表格中,当再次需要计算已经计算过的子问题时,只是在表格中简单地查看一下结果,从而获得较高的效率。
参考资料:动态规划
- 523. Continuous Subarray Sum
- 523. Continuous Subarray Sum
- 523. Continuous Subarray Sum
- 523. Continuous Subarray Sum
- 523. Continuous Subarray Sum
- 523. Continuous Subarray Sum
- 523. Continuous Subarray Sum
- 523. Continuous Subarray Sum
- 523. Continuous Subarray Sum
- 523. Continuous Subarray Sum
- 523. Continuous Subarray Sum
- 523. Continuous Subarray Sum
- 523. Continuous Subarray Sum
- 523. Continuous Subarray Sum
- 523. Continuous Subarray Sum
- 523. Continuous Subarray Sum
- Leetcode-523. Continuous Subarray Sum
- Leetcode 523. Continuous Subarray Sum
- easyUI 根据一些条件改变DataGrid 行背景颜色
- Android消息机制
- php 魔术方法简介
- HDU
- JAVA 线程之守护线程Daemon Thread
- 523. Continuous Subarray Sum
- uva10891
- AOJ.187图的最短路径
- 洛谷 P1049 装箱问题
- 钉钉环境下H5开发微应用遇到的问题和BUG(持续更新)
- webStorm快捷键
- 51nod -1255 字典序最小的子序列(贪心)
- Java学习路线
- Python爬虫系列之----Scrapy(一)爬虫原理