题目描述
输入一个正整数 target ,输出所有和为 target 的连续正整数序列(至少含有两个数)。
序列内的数字由小到大排列,不同序列按照首个数字从小到大排列。
示例 1:
输入:target = 9
输出:[[2,3,4],[4,5]]
示例 2:
输入:target = 15
输出:[[1,2,3,4,5],[4,5,6],[7,8]]
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/he-wei-sde-lian-xu-zheng-shu-xu-lie-lcof
代码
class Solution {
public int[][] findContinuousSequence(int target) {
// 由其特点,j 最多到 (target+1)/2,减少不必要的运算
int len=(target+1)/2, j=2,i=1;
List<int[]> n = new ArrayList<>();
while (j <= len) {
// 连续从 i 到 j 的总和
int sum = (i+j)*(j-i+1)/2;
// 如果sum < target,由 j 一直探索(扩张总和),直到 sum >= target
while (sum < target && j<=len) {
// 一开始我提交计算用的 sum = (i+j)*(j-i+1)/2;nt了,直接先对j++再sum += j就行了
// 直接导致我多耗时2ms, ****
j++;
sum += j;
}
// 如果 sum > target 开始由 i 一直探索(缩小总和),直到 sum <= target
while (sum > target && j<=len) {
// 一开始我提交计算用的 sum = (i+j)*(j-i+1)/2;nt了,直接先减去i再对i++就行了
sum -= i;
i++;
}
if (sum == target) {
n.add(getArray(i, j));
// 再次尝试扩张
j++;
}
}
// 这个转换方法有点晦涩 T[] = List.toArray(new T()) ,这里 T = int[]
return n.toArray(new int[n.size()][]);
}
/**
* 返回从 x 到 y 连续的数组:如 x=2, y=5, 返回 new int[]{2, 3, 4, 5}
*/
private int[] getArray(int x, int y) {
int len = y-x+1;
int[] array = new int[len];
int j=0;
for (int i=x; i<=y; i++) {
array[j++] = i;
}
return array;
}
}
作者:li-qiu-shui
链接:https://leetcode-cn.com/problems/he-wei-sde-lian-xu-zheng-shu-xu-lie-lcof/solution/bu-yong-shuang-zhi-zhen-nan-ding-by-li-q-ov6f/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
C++双指针
class Solution {
public:
vector<vector<int>> findContinuousSequence(int target) {
int i=1,j=2;
int mid=(target+1)/2;
vector<vector<int>> res;
int sum;
while(j<=mid&&i<j){
sum=(i+j)*(j-i+1)/2;
if(sum==target){
vector<int> arr;
for(int k=i;k<=j;k++){
arr.push_back(k);
}
res.push_back(arr);
i++;
}
else if(sum<target) j++;
else i++;
}
return res;
}
};