待字闺中之子序列分析
来源:互联网 发布:linux log4j日志查看 编辑:程序博客网 时间:2024/06/02 10:34
原题
给定长度为n的整数数列:a0,a1,..,an-1,以及整数S。这个数列会有连续的子序列的整数总和大于S的,求这些数列中,最小的长度。
分析
如果只是像题目这样的描述,没有强调正数,可以采用O(n^2)的方法。具体代码如下:
int subSeqWithNegative(vector<int>& data,int sum){int i,j,length = data.size(),res = length+1;for (i = 0;i < length;i++)//查找每一个以i开始的,满足条件的最短序列长度{j = i;int curSum = 0;while(j < length){curSum += data[j];if (curSum > sum){if(j - i + 1 < res)res = j - i + 1;break;}j++;}}if(res == length+1)return -1;//找不到大于sum的序列return res;}
但是,很多同学在讨论的时候,指出了如果是正数,解法将会有什么样的变化。这个很好。不考虑正负的O(n^2)的方法,这里不详细说了,我们来讨论,当数列中都是正数的情况。
介绍一个利用排序+二分的方法。对于子序列ai...at,子序列和s=ai+...+at=sum[t]-sum[i-1]。sum[t]表示数列a0...at的和。那么,数组sum天然就是递增的,可以进行二分查找。 那么如何进行二分查找呢?对于数组sum,遍历找到第一个k,sum[k]>S,二分查找k前面的某一个j,j是sum[k]-sum[j]>S里最大的一个,则k-j是最小的。依次遍历完数组。 可以得到最小的长度,整体的时间复杂度O(nlogn),空间复杂度为O(n)。 是否有更快的方法呢?从以上两个方法,我们可以有如下的观察:
a0...at>S,则a0...at+1无需再考虑
对于a0...at>S,只需尝试a1...at是否>S,如果大于S,则更新最短长度。
如果不大于S,大于S的只可能是a1...atat+1等。
鉴于以上的观察,我们有如下的算法:设置索引i,j指向第一个整数:
1. ++j,直到sum[j]-sum[i]>S,这里不需要额外保存sum,为了方便说明。记录子序列长度2. ++i,如果sum[j]-sum[i]>S,更新最小子序列长度。直到sum[j]-sum[i]<=S。3. ++j,直到sum[j]-sum[i]>S。重复上面的两步,直到数组遍历完毕。
整个算法的时间复杂度为O(n)。下面我们做一个示例数组为{5,1,3,5,10,7,4,9,2,8},S=10,i=j=0开始
1. 当j=3时,和为14>10,则更新最小长度为42. 对i进行递增操作,和为9<10,不满足条件。对j进行递增3. 当i=1,j=4时,和为19>10,长度为4,不更新最小长度。递增i,直到i=3,此时和15>10,更新最小长度为2,4. 依次类推
最终得到最小长度为2.具体代码如下:
int subSeqWithPositive(vector<int>& data,int sum){int i = 0 ,j = 0,length = data.size(),curSum = 0,res = length+1;while (j < length){while (curSum <= sum)//移动后指针{curSum += data[j++];if(j >= length)break;}while (curSum > sum)//移动前指针{if (res > j - i) res = j - i;curSum -= data[i++];}}return res;}
2 1
- 待字闺中之子序列分析
- 面试题之子序列分析
- 待字闺中:括号匹配分析
- 待字闺中之逆序分析
- 待字闺中之此起彼伏分析
- 动态规划之子序列与子串问题分析
- 剑指offer之寻找丑数,待字闺中之序列生成分析
- 待字闺中之Magic Index 分析
- 待字闺中之相伴一生分析
- 待字闺中之巧妙排序分析:
- 待字闺中之死亡小岛分析
- 待字闺中之interleave字符串分析
- 待字闺中之相差最大分析
- 待字闺中之兄弟数字分析
- 待字闺中之最长等差数列分析
- 待字闺中之删除字符分析
- 待字闺中之最大乘积分析
- 【待字闺中】
- Java Threads 多线程10分钟参考手册
- BZOJ1049
- expressjs路由学习记录(二)
- eclipse优化
- Java - IO - 字符流 - Writer - Reader
- 待字闺中之子序列分析
- Android系列---JSON数据解析
- C++之类的成员函数的调用 vs. 普通函数的调用
- 最短路径之Dijkstra算法
- sg函数
- Could not find XXX.apk的解决方法
- xml中的转义字符
- HDOJ 4293 dp
- Bash Scripting,read与variables(Linux)