输入一个正整数 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
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
暴力解法:滑动窗口
i j就像两个指针,指向窗口的左端和窗口的右端,窗口中囊括的数就是要进行运算并与target比较的数列。初始窗口为0,逐渐向右拉开窗户(窗口数列增大),如果拉到了窗口内和大于target而没有等于target时,说明带有1的连续数列不能满足题意。sum=sum-i,左窗沿向右拉,开始寻找从2开始的连续序列是否满足题意。
- 左右窗沿都不会向左拉(不走回头路),左边不被窗口覆盖的部分被永远舍弃。
- 此法可以找到所有满足题意的数组(1开头,2开头…直到target/2+1结尾,都会被窗口覆盖计算过)
- 规律:target一定小于等于它的 一半加上(一半+1)。n/2+(n/2+1)=n+1 //且除号运算向下取整
- 因此我们可以得到:右边界一定小于等于 target/2
int** findContinuousSequence(int target, int* returnSize, int** returnColumnSizes)
{
int i=1,j=1,sum=0;
int v,temp,k;
int** res=(int**)calloc(target,sizeof(int*));
*returnSize=0;
*returnColumnSizes=(int*)calloc(target,sizeof(int));
while(i<=target/2)
{
if(sum<target)
{
sum+=j;
j++;
}
else if(sum>target)
{
sum-=i;
i++;
}
else
{
temp=i;
(*returnColumnSizes)[*returnSize]=j-i;
res[*returnSize]=(int*)calloc(j-i,sizeof(int));
for(v=i,k=0;v<j;v++,k++,temp++)
{
res[*returnSize][k]=temp;
}
(*returnSize)++;
sum-=i;
i++;
}
}
return res;
}