题目
给定一个整数数组 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) };