好歹是按自己的思路写出来了。。。。耗时2h
题目描述
输入一个正整数
target
,输出所有和为target
的连续正整数序列(至少含有两个数)。序列内的数字由小到大排列,不同序列按照首个数字从小到大排列。
我的思路
首先这题没给我数组,我就自己搞了个0-100的数列,根据题目的输出示例,观察到输出的数组总会在target的(一半+1)以下,这样就可以减少一些查找量。这里需要注意的是,JavaScript的除法是直接除可以有小数的,不同于c/c++。因此我就向下取整了(向上取整会更好点),然后新建一个不知道长度的数组就直接const res=[]即可,后面会往里面放东西,因此不需要fill(0)。
其次开始循环找几个重要数值,n(返回数组里有几组数组),flag&outFlag(加了几轮,也就意味着一个小数组里有几个数),num(一个小数组里最大的数)。需要注意的是,因为设置的参数有点多,所以最好写好注释以免搞混了。我一开始的时候犯了一个很愚蠢的错误,直接把j拿到while循环里加给sum,同时j也会自加,导致外层for循环只循环了一次就出来了,我还一直在找为什么。
因此最好不要在for循环里改变j这类数的值。
接着就是对每个参数的规则添加,flag因为需要清0,所以要给一个outFlag出来。
关于这个outFlag又有一个小问题,因为是在for循环里while,所以有些outFlag存在为0的情况,这个outFlag直接关系到一个小数组里有几个数,就是如果有数下来的话,下面的while循环也会创建一个空的新数组,所以要规避掉这些没用的0,就搞一个if,如果不为0,才执行下面的步骤。
最后就是如何把小数组放进返回数组里,这里我是看了一下别人的题解的,因为本人只懂push,但是push进去以后输出空值。别人的办法是使用splice(0)方法拷贝数组,再把数组push进返回数组里。
我的代码
/**
* @param {number} target
* @return {number[][]}
*/
var findContinuousSequence = function(target) {
const nums=new Array(100);
let sum=0,num=0,n=0,t=0,flag=0,outFlag=0;
for(let i=0;i<nums.length;i++)
{
nums[i]=i;
}
//向下取整
let a=Math.floor(target/2);
const res=[];
for(let j=1;j<=a+1;j++)
{
sum=0,t=j;
flag=0;
while(t<=a+1)
{
sum+=t;
//加了几轮
flag++;
if(sum==target)
{
//n代表了数组里有几组数组
n++;
//num代表数组里最大的那个数
num=t;
//outflag代表了数组里有几个数,也就是加了几次
outFlag=flag;
flag=0;
break;
}
t++;
if(sum>target)
{
break;
}
}
console.log(outFlag);
//输出数组
if(outFlag!=0)
{
const tarr=new Array(outFlag);
while(num>0&&outFlag>0)
{
tarr[outFlag-1]=num;
num--,outFlag--;
}
res.push(tarr.slice(0));
}
}
return res;
};
官方题解
官方使用了滑动窗口的方法,这里我看的是(作者:爱吃糖的猫
链接:https://leetcode.cn/problems/he-wei-sde-lian-xu-zheng-shu-xu-lie-lcof/solutions/1956261/yi-chong-hao-li-jie-de-hua-dong-chuang-k-lm4o/)的方法。非常简洁。
这里的Math.ceil()方法就是向上取整。
如果sum比target大了,就移除前面的数,如果相等,就push进返回数组。
然后shift是删除头部的数,unshift是在头部添加数。
具体的可以看掘金的这篇:js数组常用方法(19种)|你会的到底有多少呢? - 掘金 (juejin.cn)
var findContinuousSequence = function(target) {
let sum = 1 //窗口数组的和
let list =[1] //窗口
let returnList =[]
for(let i = 2 ; i<= Math.ceil(target/2) ; i++) {
sum+=i
list.push(i) //每次循环,都将当前的数加入滑动窗口中
while(sum>target){
sum-=list.shift() //移除前面较小的数
}
if(sum==target){
returnList.push(list.slice(0)) //slice深拷贝
}
}
return returnList
};