1. Topic
Input a positive integer target, and output all consecutive positive integer sequences (containing at least two numbers) whose sum is target.
The numbers in the sequence are arranged from smallest to largest, and different sequences are arranged from smallest to largest according to the first number.
Example 1:
输入:target = 9
输出:[[2,3,4],[4,5]]
Example 2:
输入:target = 15
输出:[[1,2,3,4,5],[4,5,6],[7,8]]
limit:
- 1 <= target <= 10^5
Two, solve
1. Sliding window
Ideas:
Sliding array : can be seen as a framed part of the array . For programming convenience, it is set to left closed and right open interval .
Initial values : i=1, j=1, the sliding window is located at the leftmost side of the sequence, and the window size is 0.
Nature : The left and right borders of the window can always only move to the right , but not to the left.
Process :
- Definition : the sum of several numbers in the window
sum
, the left end pointi
and the right end pointj
. - Window movement and result recording :
2.1. ifsum < target
,sum
need to increase, that is, expand the window, and the right margin will move to the rightj++
;
2.2. ifsum > target
,sum
need to decrease, that is, shrink the window, and move the left margin to the righti++
,;
2.3. ifsum = target
, record the result at this time, that is Note down[i, j)
the elements. This is also the onlyi
sequence at the beginning. Next, move the left margin to the righti++
,; - After the traversal is complete, the result set is returned .
Question : Can the window move find all the solutions?
分析:
1) 1 + 2 +...+ 8 < target
2) 1 + 2 +...+ 8 + 9 > target
由1)2)可得,说明 1 开头的序列找不到解。
3)寻找以2开头的序列:2+...+8 < 1+2+...+8 < target.
2+3+...+8+9 ? target,如果两端相等,则记录下该序列,然后左边界右移。
结论:该2开始的序列唯一。
进一步推论,每个元素开始的序列都有判断,如果与target相等,均唯一,所以能找到全部解。
Code:
class Solution {
public int[][] findContinuousSequence(int target) {
int i = 1; // 滑动窗口的左边界
int j = 1; // 滑动窗口的右边界
int sum = 0; // 滑动窗口中数字的和
List<int[]> res = new ArrayList<>();
while (i <= target / 2) {
if (sum < target) {
// 右边界向右移动
sum += j;
j++;
} else if (sum > target) {
// 左边界向右移动
sum -= i;
i++;
} else {
// 记录结果
int[] arr = new int[j-i];
for (int k = i; k < j; k++) {
arr[k-i] = k;
}
res.add(arr);
// 左边界向右移动
sum -= i;
i++;
}
}
return res.toArray(new int[res.size()][]);
}
}
Time complexity: O (n) O(n)O ( n )
space complexity: O (n) O(n)O ( n )
2. Cumulative characteristics
Ideas:
If there are two consecutive numbers is equal target
, then the difference is 1, (target - 1) % 2 == 0
and the array must be from the (target - 1) / 2
beginning of the array element is 2
a;
If a 3
continuous array, the phase difference between the number three 1、2,(target - 1 - 2) % 3 == 0
, and the array must be from (target - 1 - 2) / 3
the beginning of the array element is 3
a;
By analogy, but note that it target
must be 0
a number greater than , and the res
order needs to be reversed. If you don’t understand it yet, you can target=9
substitute it for understanding.
Code:
class Solution {
public int[][] findContinuousSequence(int target) {
List<int[]> result = new ArrayList<>();
int i = 1;
while(target/2 > 0) {
target -= i++;
if(target>0 && target%i == 0) {
int[] array = new int[i];
for(int k = target/i, j = 0; k < target/i + i; k++, j++) {
array[j] = k;
}
result.add(array);
}
}
Collections.reverse(result);
return result.toArray(new int[0][]);
}
}
Time complexity: O (n) O(n)O ( n )
space complexity: O (n) O(n)O ( n )
Extension: similar to 829. The sum of consecutive integers , but the return value is different. Some ideas and methods can be used for reference.
Three, reference
1. What is a sliding window, and how to use a sliding window to solve this problem (C++/Java/Python)
2. Math problems, mathematical solution
3. Java double 100%