Subarray Sum K
Given an nonnegative integer array, find a subarray where the sum of numbers is k. Your code should return the index of the first number and the index of the last number.Example Given [1, 4, 20, 3, 10, 5], sum k = 33, return [2, 4].
题解1 - 哈希表
题 Zero Sum Subarray | Data Structure and Algorithm 的升级版,这道题求子串和为 K 的索引。首先我们可以考虑使用时间复杂度相对较低的哈希表解决。前一道题的核心约束条件为 f(i1)−f(i2)=0,这道题则变为 f(i1)−f(i2)=k
C++:
#include <iostream> #include <vector> #include <map>using namespace std;class Solution { public:/*** @param nums: A list of integers* @return: A list of integers includes the index of the first number* and the index of the last number*/vector<int> subarraySum(vector<int> nums, int k){vector<int> result;// curr_sum for the first item, index for the second item// unordered_map<int, int> hash;map<int, int> hash;hash[0] = 0;int curr_sum = 0;for (int i = 0; i != nums.size(); ++i) {curr_sum += nums[i];if (hash.find(curr_sum - k) != hash.end()) {result.push_back(hash[curr_sum - k]);result.push_back(i);return result;} else {hash[curr_sum] = i + 1;}}return result;} };int main(int argc, char *argv[]) {int int_array1[] = {1, 4, 20, 3, 10, 5};int int_array2[] = {1, 4, 0, 0, 3, 10, 5};vector<int> vec_array1;vector<int> vec_array2;for (int i = 0; i != sizeof(int_array1) / sizeof(int); ++i) {vec_array1.push_back(int_array1[i]);}for (int i = 0; i != sizeof(int_array2) / sizeof(int); ++i) {vec_array2.push_back(int_array2[i]);}Solution solution;vector<int> result1 = solution.subarraySum(vec_array1, 33);vector<int> result2 = solution.subarraySum(vec_array2, 7);cout << "result1 = [" << result1[0] << " ," << result1[1] << "]" << endl;cout << "result2 = [" << result2[0] << " ," << result2[1] << "]" << endl;return 0; }
输出:
result1 = [2 ,4] result2 = [1 ,4]
源码分析
与 Zero Sum Subarray 题的变化之处有两个地方,第一个是判断是否存在哈希表中时需要使用hash.find(curr_sum - k)
, 最终返回结果使用result.push_back(hash[curr_sum - k]);
而不是result.push_back(hash[curr_sum]);
复杂度分析
略,见 Zero Sum Subarray | Data Structure and Algorithm
题解2 - 利用单调函数特性
不知道细心的你是否发现这道题的隐含条件——nonnegative integer array, 这也就意味着子串和函数 f(i) 为「单调不减」函数。单调函数在数学中可是重点研究的对象,那么如何将这种单调性引入本题中呢?不妨设 i2>i1, 题中的解等价于寻找 f(i2)−f(i1)=k, 则必有 f(i2)≥k.
我们首先来举个实际例子帮助分析,以整数数组 {1, 4, 20, 3, 10, 5} 为例,要求子串和为33的索引值。首先我们可以构建如下表所示的子串和 f(i).
f(i) | 1 | 5 | 25 | 28 | 38 |
---|---|---|---|---|---|
i | 0 | 1 | 2 | 3 | 4 |
要使部分子串和为33,则要求的第二个索引值必大于等于4,如果索引值再继续往后遍历,则所得的子串和必大于等于38,进而可以推断出索引0一定不是解。那现在怎么办咧?当然是把它扔掉啊!第一个索引值往后递推,直至小于33时又往后递推第二个索引值,于是乎这种技巧又可以认为是「两根指针」。
C++:
#include <iostream> #include <vector> #include <map>using namespace std;class Solution { public:/*** @param nums: A list of integers* @return: A list of integers includes the index of the first number* and the index of the last number*/vector<int> subarraySum2(vector<int> &nums, int k){vector<int> result;int left_index = 0, curr_sum = 0;for (int i = 0; i != nums.size(); ++i) {while (curr_sum > k) {curr_sum -= nums[left_index];++left_index;}if (curr_sum == k) {result.push_back(left_index);result.push_back(i - 1);return result;}curr_sum += nums[i];}return result;} };int main(int argc, char *argv[]) {int int_array1[] = {1, 4, 20, 3, 10, 5};int int_array2[] = {1, 4, 0, 0, 3, 10, 5};vector<int> vec_array1;vector<int> vec_array2;for (int i = 0; i != sizeof(int_array1) / sizeof(int); ++i) {vec_array1.push_back(int_array1[i]);}for (int i = 0; i != sizeof(int_array2) / sizeof(int); ++i) {vec_array2.push_back(int_array2[i]);}Solution solution;vector<int> result1 = solution.subarraySum2(vec_array1, 33);vector<int> result2 = solution.subarraySum2(vec_array2, 7);cout << "result1 = [" << result1[0] << " ," << result1[1] << "]" << endl;cout << "result2 = [" << result2[0] << " ," << result2[1] << "]" << endl;return 0; }
输出:
result1 = [2 ,4] result2 = [1 ,4]
源码分析
使用for
循环, 在curr_sum > k
时使用while
递减curr_sum
, 同时递增左边索引left_index
, 最后累加curr_sum
。如果顺序不对就会出现 bug, 原因在于判断子串和是否满足条件时在递增之后(谢谢 @glbrtchen 汇报 bug)。
复杂度分析
看似有两重循环,由于仅遍历一次数组,且索引最多挪动和数组等长的次数。故最终时间复杂度近似为 O(2n), 空间复杂度为 O(1).
转载于:https://www.cnblogs.com/lyc94620/p/10119735.html
Subarray Sum K相关推荐
- LeetCode Subarray Sum Equals K
原题链接在这里:https://leetcode.com/problems/subarray-sum-equals-k/description/ 题目: Given an array of integ ...
- LeetCode 325. Maximum Size Subarray Sum Equals k
这一题开始以为是sliding window,后来发现,因为有负数,sum不具有单调性,没有办法用slidng window找出optimal solution. 如果考虑brute force的做法 ...
- LintCode 402: Continuous Subarray Sum
LintCode 402: Continuous Subarray Sum 题目描述 给定一个整数数组,请找出一个连续子数组,使得该子数组的和最大.输出答案时,请分别返回第一个数字和最后一个数字的下标 ...
- [LintCode] Minimum Size Subarray Sum 最小子数组和的大小
Given an array of n positive integers and a positive integer s, find the minimal length of a subarra ...
- Leetcode 560. Subarray Sum Equals K
前缀和(prefix sum/cumulative sum) import collectionsclass Solution(object):def subarraySum(self, nums, ...
- LeetCode 523. Continuous Subarray Sum
题目: Given a list of non-negative numbers and a target integer k, write a function to check if the ar ...
- LeetCode-Easy部分中标签为Dynamic Programming 523. Continuous Subarray Sum
原题 Given a list of non-negative numbers and a target integer k, write a function to check if the arr ...
- [JAVA]寻找满足和的最短子序列(Minimum Size Subarray Sum)
题目来源:leetcode 题目描述: Given an array of n positive integers and a positive integer s, find the minimal ...
- 523. Continuous Subarray Sum
class Solution { public:bool checkSubarraySum(vector<int>& nums, int k) {unordered_map< ...
- leetcode523 Continuous Subarray Sum
思路: 令sum[p]表示p位置的前缀和.如果sum[i] % k == sum[j] % k (j - i > 1),则存在子段(i, j]的和能够整除k. 实现: 1 class Solut ...
最新文章
- linux下文件夹函数,如何从linux上的文件夹中找到一个函数
- activiti监听器使用
- 什么是区块链钱包?区块链钱包如何运作?
- 跟着别人的感觉做网络推广之二
- OpenJudge计算概论-最长单词2
- 2018全球大学AI排名发布,中国高校表现强势!
- 8. OD-输入错误的信息注册未注册的软件
- docker和数据卷问题探究
- 智能指针(一):STL auto_ptr实现原理
- f-stack nginx 多进程模式启动 main_loop 流程分析
- Centos7 设置环境变量
- 【.Net MF网络开发板研究-06】以太网转串口
- 服务器安装esxi系统
- Blender3.0资产浏览器
- Unity3D新手入门教程_游戏开发100集课程 (含粒子
- 阿里云服务器怎么重置密码?服务器登录密码忘记了怎么办?
- 【原创】微信双开是定时炸弹?关于非越狱iOS上微信分身高危插件ImgNaix的分析
- 大屏可视化低代码开发平台网址
- 中船嘉年华邮轮揭幕全新企业品牌标识;美国运通全球商务旅行完成对Expedia集团旗下易信达的收购 | 全球旅报...
- 月薪3500的我,是怎样把自己 “逼”成月入十万的?
热门文章
- k-近邻算法 ---sklearn
- AttributeError: ‘Polygon‘ object has no property ‘normed‘
- 安装opcenccv-python以后仍然No module named ‘cv2‘
- conda: command not found
- 【Caffe代码解析】Layer网络层
- python日期模块datetime常用操作总结(字符串与datetime对象互转、日期差值计算、时间戳获取、时间数组生成等)
- 基于网页分析构思出的正文提取算法
- 很特别的动态规划教程
- java和python互相调用
- 机器学习(二)——贝叶斯算法