🚩传送门:牛客题目
力扣题目

题目

输入一个正整数 [NC]256. 和为 s 的连续正数序列 - 图1 ,输出所有和为 [NC]256. 和为 s 的连续正数序列 - 图2 的连续正整数序列(至少含有两个数)。

序列内的数字由小到大排列,不同序列按照首个数字从小到大排列。

示例 1:

输入:target = 9 输出:[[2,3,4],[4,5]]

示例 2:

输入:target = 15 输出:[[1,2,3,4,5],[4,5,6],[7,8]]

解题思路:滑动窗口 [ 双指针 ]

设连续正整数序列的左边界 [NC]256. 和为 s 的连续正数序列 - 图3 和右边界 [NC]256. 和为 s 的连续正数序列 - 图4 ,则可构建滑动窗口从左向右滑动。循环中,每轮判断滑动窗口内元素和与目标值 [NC]256. 和为 s 的连续正数序列 - 图5 的大小关系

  • 若相等则记录结果
  • 若大于 [NC]256. 和为 s 的连续正数序列 - 图6 则移动左边界 [NC]256. 和为 s 的连续正数序列 - 图7 (以减小窗口内的元素和)
  • 若小于 [NC]256. 和为 s 的连续正数序列 - 图8 则移动右边界 [NC]256. 和为 s 的连续正数序列 - 图9(以增大窗口内的元素和)

[NC]256. 和为 s 的连续正数序列 - 图10

复杂度分析

时间复杂度:[NC]256. 和为 s 的连续正数序列 - 图11,其中 [NC]256. 和为 s 的连续正数序列 - 图12 为数组长度,两个指针移动的总次数最多为 [NC]256. 和为 s 的连续正数序列 - 图13

空间复杂度:[NC]256. 和为 s 的连续正数序列 - 图14,使用常数大小的额外空间。

官方代码

  1. class Solution {
  2. public int[][] findContinuousSequence(int target) {
  3. int i = 1, j = 2;
  4. List<int[]> res = new ArrayList<>();
  5. while (i < j) {
  6. int sum = (i + j) * (j - i + 1) / 2;
  7. if (sum == target) {
  8. int[] ans = new int[j - i + 1];
  9. for (int k = i; k <= j; k++)
  10. ans[k - i] = k;
  11. res.add(ans);
  12. }
  13. if (sum > target) i++;
  14. else j++;
  15. }
  16. return res.toArray(new int[0][]);
  17. }
  18. }