题目描述:
输入一个正整数 target ,输出所有和为 target 的连续正整数序列(至少含有两个数)。
序列内的数字由小到大排列,不同序列按照首个数字从小到大排列。
示例 1:
输入:target = 9
输出:[[2,3,4],[4,5]]
示例 2:
输入:target = 15
输出:[[1,2,3,4,5],[4,5,6],[7,8]]
限制:
1 <= target <= 10^5
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/he-wei-sde-lian-xu-zheng-shu-xu-lie-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/he-wei-sde-lian-xu-zheng-shu-xu-lie-lcof 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路
n个相邻的数相加的结果是n*这个n个数的平均值,但是平均值可能会有0.5的情况出现(奇数)
一个奇数数 /2 得到的那个0.5的数字 附近的两个数字可以成为其相加的结果,15 = 7 ,8
除以3得到的那个数字周围三个数字,(如果是除的数字是奇数,就看结果是不是整数)
除以4得到的那个数字周围的4个数字,(如果除的数字是偶数,就看这个结果 和 结果+1 加起来乘n 再除2是不是这个数)
除以5得到的那个数字周围的5个数字,
。。。。
直到这个数字的平方大于他自己
注意要判断是要从1开始,结果不能小于n/2
代码
class Solution {
public:
vector<vector<int>> findContinuousSequence(int target) {
vector<vector<int>> ans;
int i = target/2+1; //能不能剪枝呢?试试target/2 + 1
while(i>1){
int tmp_cent = target/i;
if(i%2==0){
//偶数个组合
if(i*(tmp_cent + tmp_cent + 1) == 2*target){
vector<int> tmp_ans;
int tmp = tmp_cent-i/2+1;
if(tmp>0){
for(int j = tmp;j<tmp+i;j++){
tmp_ans.push_back(j);
}
ans.push_back(tmp_ans);
}
}
}else{
//奇数个组合
if(i*tmp_cent == target){
vector<int> tmp_ans;
int tmp = tmp_cent-i/2;
if(tmp>0){
for(int j = tmp;j<tmp+i;j++){
tmp_ans.push_back(j);
}
ans.push_back(tmp_ans);
}
}
}
i--;
}
return ans;
}
};
分析
时间复杂度:由于枚举以后只需要 O(1) 的时间判断,所以时间复杂度为枚举起点的复杂度O(target) 。
空间复杂度:O(1),除了答案数组只需要常数的空间存放若干变量。