题目描述:

  1. 输入一个正整数 target ,输出所有和为 target 的连续正整数序列(至少含有两个数)。
  2. 序列内的数字由小到大排列,不同序列按照首个数字从小到大排列。
  3. 示例 1
  4. 输入:target = 9
  5. 输出:[[2,3,4],[4,5]]
  6. 示例 2
  7. 输入:target = 15
  8. 输出:[[1,2,3,4,5],[4,5,6],[7,8]]
  9. 限制:
  10. 1 <= target <= 10^5
  11. 来源:力扣(LeetCode
  12. 链接:https://leetcode-cn.com/problems/he-wei-sde-lian-xu-zheng-shu-xu-lie-lcof
  13. 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

来源:力扣(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

代码

  1. class Solution {
  2. public:
  3. vector<vector<int>> findContinuousSequence(int target) {
  4. vector<vector<int>> ans;
  5. int i = target/2+1; //能不能剪枝呢?试试target/2 + 1
  6. while(i>1){
  7. int tmp_cent = target/i;
  8. if(i%2==0){
  9. //偶数个组合
  10. if(i*(tmp_cent + tmp_cent + 1) == 2*target){
  11. vector<int> tmp_ans;
  12. int tmp = tmp_cent-i/2+1;
  13. if(tmp>0){
  14. for(int j = tmp;j<tmp+i;j++){
  15. tmp_ans.push_back(j);
  16. }
  17. ans.push_back(tmp_ans);
  18. }
  19. }
  20. }else{
  21. //奇数个组合
  22. if(i*tmp_cent == target){
  23. vector<int> tmp_ans;
  24. int tmp = tmp_cent-i/2;
  25. if(tmp>0){
  26. for(int j = tmp;j<tmp+i;j++){
  27. tmp_ans.push_back(j);
  28. }
  29. ans.push_back(tmp_ans);
  30. }
  31. }
  32. }
  33. i--;
  34. }
  35. return ans;
  36. }
  37. };

分析

时间复杂度:由于枚举以后只需要 O(1) 的时间判断,所以时间复杂度为枚举起点的复杂度O(target) 。

空间复杂度:O(1),除了答案数组只需要常数的空间存放若干变量。