您的位置:首页 > Web前端

剑指offer-和为S的连续正数序列-两根指针

2017-02-11 16:19 281 查看

问题

题目:[和为S的连续正数序列]

思路

这个题吧,出的确实挺好的。

和上个题完美演绎了两根指针的用法。

第一次错误是因为,这两个虽然很像,但是两根指针的意义并不同。

并且开始时的位置也不同。

本题,我之所以前面做错了,因为把两根指针意义没搞懂。

上个题,small较小数。big是较大数。如果和较大, –big。反之,++small

但是,这个题目不一样,low和high是区间。如果区间和小,high应该增大,相当于增加区间长度。如果和较大,那么应该缩短区间长度,low++。需要注意,其实缩小区间长度,high–也可以。但是因为这回合之前的情形重叠,所以规定都向前走。

代码

class Solution {
public:
vector<vector<int> > FindContinuousSequence(int sum) {
vector<vector<int>> ret;
int mid = sum/2;
int low = 1;
int high = 2;

while(low < high && low <= mid){
int t = acc(low, high);
if(t == sum){
vector<int> v;
for(int k = low; k <= high; ++k){
v.push_back(k);
}
ret.push_back(v);
++low;
}
else if(t<sum) ++high;
else ++low;
}
return ret;
}
private:
int acc(int low, int high){
int sum = 0;
while(low <= high){
sum += low;
++low;
}
return sum;
}
};


思路1

来了一次暴力法,这个题虽然过了,但是这个方法有很明显的问题,当sum很大时其实,我没有对区间做很好的判定,只是过了而已。

代码1

class Solution {
public:
vector<vector<int> > FindContinuousSequence(int sum) {
vector<vector<int>> ans;
if(1==sum) return ans;

for(int begin = 1; begin < 20; ++begin){
int cur = begin;
int j ;
for( j = begin + 1; cur < sum ; ++j){
cur += j;
}
--j;
if( cur == sum && cur != begin ){
vector<int> ret;
for(int  p = begin; p <= j; ++p){
ret.push_back( p );
}
ans.push_back(ret);
}
}
return ans;
}
};


代码1

[参考新的方法]

class Solution {
public:
vector<vector<int> > FindContinuousSequence(int sum) {
vector< vector<int> > ret;
if( sum <= 2 ) return ret;

int small = 1;
int big = 2;
int cur = 3;

int mid = sum/2;

while(small <= mid) {
if( cur == sum ){
vector<int> t;
for(int i = small; i <= big; ++i) t.push_back(i);
ret.push_back(t);

cur -= small;
++small;
}
else if( cur < sum ) { ++big; cur += big; }
else { cur-= small; ++small; }
}

return ret;
}
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: