JS算法-轮转数组

132 阅读2分钟

题目

给定一个整数数组 nums,将数组中的元素向右轮转 k **个位置,其中 k **是非负数。

输入:nums = [-1,-100,3,99], k = 2
输出:[3,99,-1,-100]
解释: 
向右轮转 1 步: [99,-1,-100,3]
向右轮转 2 步: [3,99,-1,-100]

题解

第一种

首先将数组nums反转,即原来的最后一个元素变成了第一个元素,原来的第一个元素变成了最后一个元素,依次类推,然后对k取模,这一步是为了防止k的值大于数组长度,因为大于数组长度的移动是多余的,所以只需移动k%nums.length个元素即可,然后将数组nums分为两部分,前k个元素和后面的元素。对前k个元素进行反转,即原来的第一个元素变成了第k个元素,原来的第二个元素变成了第k-1个元素,依次类推,最后对后面的元素进行反转,即原来的第k+1个元素变成了倒数第二个元素,原来的第k+2个元素变成了倒数第三个元素,依次类推,返回最终的数组nums

var rotate = function(nums, k) {
  nums.reverse();
  k %= nums.length; 
  let left = 0;
  let right = k-1;
  while(left<right) {
      [nums[left++], nums[right--]] = [nums[right],nums[left]];
  }
  left = k;
  right = nums.length-1;
  while(left<right) {
      [nums[left++], nums[right--]] = [nums[right],nums[left]];
  }
  return nums;
};

第二种

定义了一个 reverse 函数,用来反转数组中指定部分的元素。具体实现就是利用双指针,将指定部分的元素逆序交换,然后在rotate 函数中先将 k 取余数组长度,避免 k 的值大于数组长度的情况。然后调用三次 reverse 函数,分别是将整个数组逆序、将前 k 个元素逆序、将后面剩余的元素逆序。这样就可以实现将数组向右旋转 k 步的功能

 const reverse = (nums, start, end) => {
     while(start < end){
         const temp = nums[end]
         nums[end] = nums[start]
         nums[start] = temp
         start++
         end--
     }
 }
var rotate = function(nums, k) {
    k %= nums.length
    reverse(nums, 0, nums.length-1)
    reverse(nums, 0, k-1)
    reverse(nums, k, nums.length-1)
};

坚持努力,无惧未来!