数组旋转代码演示和单元测试

148 阅读1分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第29天,点击查看活动详情

例子:

将一个数组旋转k步,输入一个数组[1,2,3,4,5,6,7],k=3,即旋转3步,输出[5,6,7,1,2,3,4].

两种思路:

1.将末尾的数字pop取出k个,每取出一个数字就unshift放在原数组前。

function fn1(arr:number[],k:number):number[]{
	const length = arr.length;
	if(!k || length===0) return arr;
	const step = Math.abs(k%length); //取绝对值
        //时间复杂度O(n^2)
	for(let i = 0;i<step;i++){
		const n = arr.pop(); //定义n为临时变量,不占用空间,故空间复杂度O(1)
		if(n!=null){
                arr.unshift(n);//unshift时间复杂度O(n)
            } 
	}
	return arr;
}
console.log(fn1([1,2,3,4,5,6,7],3),“fn1”)

2.将后k个元素和前length-k个元素使用slice方法分割开,然后使用concat连接到一起。

function fn2(arr:number[],k:number):number[]{
	const length = arr.length;
	if(!k || length===0) return arr;
	const step = Math.abs(k%length);
        //时间复杂度O(1)
	const part1 = arr.slice(-step);
        //(使用slice方法原数组不变
        //所以时间复杂度仍然为O(1))
	const part2 = arr.slice(0,length-step);//但额外定义变量比较占用空间
	const result = part1.concat(part2);
	return result;
}
console.log(fn2([1,2,3,4,5,6,7],3),"fn2")

进行单元测试:打开终端输入npx jest + 代码目录(src/01-单元测试)

describe("数组旋转",()=>{
        //每个it都是一次测试
	it('正常情况',()=>{
		const arr = [1,2,3,4,5,6,7]
		const k = 3;
		const res = fn1(arr,k)
		expect(res).toEqual([5,6,7,1,2,3,4])//断言
	})
	it('数组为空',()=>{
		const res = fn1([],3)
		expect(res).toEqual([])//断言
	})
	it('k是负值',()=>{
		const res = fn1([1,2,3,4,5,6,7],-3);
		expect(res).toEqual([5,6,7,1,2,3,4]) //断言
	})
})

复杂度分析:

思路1:时间复杂度O(n^2),空间复杂度O(1)

思路2:时间复杂度O(1),空间复杂度O(n)

(unshift(O(n)),shift,splice都很慢。影响时间复杂度)

故选择思路二。