zoukankan      html  css  js  c++  java
  • Rotate Array 旋转数组 JS 版本解法

    Given an array, rotate the array to the right by k steps, where k is non-negative.

    给定一个数组,并且给定一个非负数的值k, 把数组往右旋转k步,要求不返回新的数组,直接改变原数组

    例子1:

    给定数组: [1,2,3,4,5,6,7] 给定 k = 3
    输出数组: [5,6,7,1,2,3,4]
    解析:
    往右旋转1步: [7,1,2,3,4,5,6]
    往右旋转2步: [6,7,1,2,3,4,5]
    往右旋转3步: [5,6,7,1,2,3,4]


    我的初步解法
    var rotate = function(nums, k) {
        let tempArr = nums.slice(0, nums.length-k) // 首先截取数组前半段保存到一个新的数组tempArr里
        nums.splice(0, nums.length-k) // 使用splice直接截去前半段数组,只保留后半段子数组到nums里
        for(let i=0; i<tempArr.length; i++){ // 循环遍历tempArr,把元素一个个push到nums里
            nums.push(tempArr[i])
        }
         console.log(nums)
    };

    这个解法并没有通过leetCode的检查,原因是,当我的数组

    nums = [1,2]

    k =3

    的时候并没有返回正确的值,这是因为这里,没有考虑到 k 的值大于数组长度的情况,于是,我又修改了一下逻辑,增加了对这种情况的判断

    var rotate = function(nums, k) {
        if(nums.length < k){ // 在这里增加对k>nums.length这种情况的判断
            k = k-nums.length
        }
        let tempArr = nums.slice(0, nums.length-k)
        nums.splice(0, nums.length-k) 
        for(let i=0; i<tempArr.length; i++){
            nums.push(tempArr[i])
        }
         console.log(nums)
    };

    至此,就满足了上面nums=[1,2] ,k=3的情况,并且也成功通过了leetCode的检测

    但是,后来发现,假如我把k增大到 nums长度的几倍以后,程序就不管用了,不会旋转,原因是 数组长度只有2,当我设k为8的时候,k = k-nums.length, 这里k还是等于6,所以,slice(0,6)和splice(0,6)方法都不起作用,下标超出了数组长度

    参考了别人的解答之后,发现求模才是万能的啊,于是乎改成这样

    var rotate = function(nums, k) {
        k %= nums.length // 求模
        let tempArr = nums.slice(0, nums.length-k)
        nums.splice(0, nums.length-k) 
        for(let i=0; i<tempArr.length; i++){
            nums.push(tempArr[i])
        }
         console.log(nums)
    };

    从上面这道题里面收获良多,一个是对slice和splice用法的理解更深入了一些,另一个是程序的严谨性,一定要考虑多种可能情况,发散思维,各种边界值也要考虑到

    以下是别人的JS解法

    解法一:

    每个数组元素的index,直接加上k,比如下图中的k=2,加完之后也要考虑index值大于数组长度的情况比如元素6加2之后是7,超出长度6, 则元素6的新index应该为1(7-6=1),

    跟上面一样,需要考虑k几倍大于数组length的情况,所以还是采用求模的方式

    var rotate = function(nums, k) {
        let tempArr = [] 
        for(let i=0; i<nums.length; i++){ // 用一个新的数组保存旋转之后的数组
            tempArr[(i+k) % nums.length] = nums[i] 
        }
        for(let j=0; j<nums.length; j++){ // 让原数组等于旋转后的新数组,改变原数组
            nums[j] = tempArr[j]
        }
        console.log(nums)
    };

    解法二,利用pop 和unshift,非常简洁,Awesome!

    var rotate = function(nums, k) {
        k %= nums.length
        for(var i = 0; i < k; i ++){
            nums.unshift(nums.pop()); //先把元素从最末尾取出来之后,再放到最前面
        }
        console.log(nums)
    };

    解法三,利用ushift 和 splice,也是非常好的方法

    var rotate = function(nums, k) {
        k %= nums.length
        nums.unshift(...nums.splice(nums.length - k, k)); //...不能少,否则会把整个截取出来的数组作为一个元素放到nums里
        console.log(nums)
    };
     
  • 相关阅读:
    面试问题之C++语言:C++中指针和引用的区别
    手撕代码:最长回文子串
    手撕代码:求字符串最长回文子序列
    手撕代码:用宏来实现获取数组的大小
    手撕代码之线程:thread类简单使用
    面试问题之计算机网络:OSI七层网络模型及相关协议
    C++各种输入
    C printf格式化输出
    记一次mac 安装MySQL-python 的惨痛经历
    记一次tomcat程序运行慢的处理过程
  • 原文地址:https://www.cnblogs.com/daisygogogo/p/9115968.html
Copyright © 2011-2022 走看看