题目描述
方法一:数学方法
头一次自己想的方法不仅能通过,而且效率还挺高,先看一下数学方法的提交结果
其实思路也很简单:分析题目可知得到的序列为等差数列,那我们只要知道每个序列的起始值以及序列的长度,我们就可以构造出整个序列,然后用一个临时的vector保存此序列,最后将临时的vector加入二维数组(vector<vector> res)即可
- 首先确定序列的大小,序列的大小为 [2,sqrt(2*target)]
- 因为当序列起始值为1时构造序列,序列长度最长,由等差数列公式可知此时长度就是sqrt(2*target)
- 有了序列的长度n,又有了等差数列的和target,现在就可以求得数列的起始值,然后构造数列了。起始值s,数列长度n,目标值target三者满足如下关系才可构造数列
( 2 ∗ s + n − 1 ) ∗ n / 2 = t a r g e t \quad\quad\quad\quad\quad\quad(2*s+n-1)*n/2 = target (2∗s+n−1)∗n/2=target- 此时要想完美地求得数列的起始值,我们需要
2 ∗ t a r g e t / n 2* target/n 2∗target/n 和 ( 2 ∗ t a r g e t / n + 1 − n ) / 2 (2*target/n+1-n)/2 (2∗target/n+1−n)/2 同时为整数,满足此条件就可以构造等差数列了
- 此时要想完美地求得数列的起始值,我们需要
附上代码:
vector<vector<int>> findContinuousSequence(int target) {
vector<vector<int>> res;
for(int n=(int)sqrt((double)target*2); n>=2; n--){
if(2*target%n==0 && (2*target/n+1-n)%2==0){
int s = (2*target/n+1-n)/2;//s表示数列起始值
if(s < 1) continue;//起始值必须为正整数
vector<int> temp;
int len = n;
while(len-- > 0){
temp.push_back(s++);
}
res.push_back(temp);
}
}
return res;
}
方法二:滑动窗口
也挺好理解的,我就不写分析过程了,参考题解:滑动窗口
int getSum(int left , int right){
int res = 0;
for(int i=left; i<=right; i++){
res += i;
}
return res;
}
vector<vector<int>> findContinuousSequence(int target) {
vector<vector<int>> res;
int left = 1;
int right = left + 1;
while( left <= target/2 ){
int sum = getSum(left, right);
if(sum < target){
right++;
continue;
}else if(sum > target){
left++;
continue;
}else{
vector<int> temp;
for(int i=left; i<=right; i++){
temp.push_back(i);
}
res.push_back(temp);
left++;
right++;
}
}
return res;
}
不用每次调用getsum函数的代码
vector<vector<int>> findContinuousSequence(int target) {
vector<vector<int>> res;
int left = 1;
int right = left + 1;
int sum = getSum(left, right);
while( left <= target/2 ){
if(sum < target){
//先移动右侧窗口再修改sum值
right++;
sum += right;//此时的区间和
}else if(sum > target){
//先修改sum值,再移动左侧窗口
sum -= left;
left++;
}else{
vector<int> temp;
for(int i=left; i<=right; i++){
temp.push_back(i);
}
res.push_back(temp);
sum -= left;
left++;//窗口左边界向右移动
right++;//由于左边界移动了,显然右边界也要向右移动
sum += right;
}
}
return res;
}