当前位置: 首页 > Web前端 > HTML5

JavaScript系列——数组元素左右移动N位算法实现

时间:2023-04-05 22:11:43 HTML5

简介刚毕业的时候,去一家公司面试。无疑被面试官视为菜鸟。最近刚好在研究数组的各种算法实现,想到了这个问题。我可以用它来实现它,纪念我逝去的青春。需求假设有这样一个数组[1,2,3,4,5],现在要左移或右移N位,比如移动1位//左移1位[2,3,4,5,1]//右移1位[5,1,2,3,4]算法实现这样的题目,不要看我下面的代码,自己想想怎么实现,是不是复杂或简单的方法。先告诉你,我用了两行代码左右移动元素。split方法在没有具体思路的时候,我们先假设数组移动1位。[1,2,3,4,5]=>[null,1,2,3,4]和[5,null,null,null,null]=>[5,1,2,3,4]可以看成是两个数组,一个是没有到达边界的元素移动[null,1,2,3,4],一个是已经到达边界的元素移动[5,null,null,null,null],当元素到达边界时,会移动到数组的初始位置,形成一个循环过程。显然,如果我们将这2个移位数组组合起来,就是我们想要的结果。移动2位也符合移动的两个数组合并为结果[1,2,3,4,5]=>[null,null,1,2,3]和[4,5,null,null,null]=>[4,5,1,2,3]只需移动数组长度[1,2,3,4,5]=>[1,2,3,4,5]和[]//如果不是,就假设合并空数组,假设数组移动1。在上面的步骤中,我们找到了规则,接下来要做的就是找到2个数组,我们需要用slice截取数组元素。截取第一个数组arr.slice(0,-1)//[1,2,3,4]截取第二个数组arr.slice(-1)//[5]合并数组arr.slice(-1).concat(arr.slice(0,-1))//[5,1,2,3,4]这样就可以实现移动1位的情况,然后,继续取范围+5和-5测试数字,发现可以正常移动。当数字大于5或小于-5时,代码无效,一直输出[1,2,3,4,5]arr.slice(-6).concat(arr.slice(0,-6))//[1,2,3,4,5]我们加个求余的小技巧,假设是移动6,那么其实和移动1是一样的,我们可以根据公式计算余数n=n%arr.length//n=6%5余数为1。同理,当移动-6n=n%arr.length//n=-6%5余数为-1然后带入公式和发现输出全部正确!!分析完思路,应该就很清楚了。源代码如下。算法源码arr代表原数组,n代表移动距离。它可以是正数、0或负数。正数表示右移,负数表示左移。,0表示没有移动。functionmoveElement(arr,n){if(Math.abs(n)>arr.length)n=n%arr.lengthreturnarr.slice(-n).concat(arr.slice(0,-n))}//moveElement(arr,9)//moveElement(arr,0)//moveElement(arr,-9)总结如果下次面试继续遇到这个问题,也许我会当场忘记自己的想法?补充看评论讨论不同解法的实现,这些很厉害,没有唯一答案,而且在思考解法的时候一定要考虑时间复杂度,移动数组的元素会引起数组的重排。我觉得第一步应该是找到最小移动位置的代价,即移动2和移动2n是一样的,我们只需要移动2,不需要移动n。求余数的函数就在这里。两个数组在不移动元素的情况下分开。最后,我使用concat合并两个数组并返回数组的新副本,这避免了移动元素。另一种解决方案是使用newSet(array1)和newSet(array2)将两个数组设置为一个集合。set是key和value的哈希表,可以用最小的代价移动位置,不会引起重排。使用集合移动之后,Array.from()转换回数组。不要试图直接修改原数组的元素位置,这样代价很大,尤其是数组长度很长的时候!!