LeetCode_14:Rotate Array

1、总结
  • 我还是有偷懒的概念的,每次实现暴力破解法都跟挤牙膏似的;
  • 题目中说至少有三种解决办法,我只写了JavaScript函数和暴力破解法,我记得线性代数中还有关于矩阵的运算方法,但是具体实现已经还给老师了。
  • 数组元素移动K位后的index计算公式:(i+k) % nums.length
  • do {...} while () 语法
  • 这道题要求至少三种解法,可惜的是我只写出来两种偷懒的方法,其实像方法三的一次移动三位,方法四的接力轮询(自己取的名字)等方法,都是有过念头但没有动手实践,以后做事情,一要上手,二要效率
2、题目

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

	Input: [1,2,3,4,5,6,7] and k = 3
	Output: [5,6,7,1,2,3,4]
	Explanation:
	rotate 1 steps to the right: [7,1,2,3,4,5,6]
	rotate 2 steps to the right: [6,7,1,2,3,4,5]
	rotate 3 steps to the right: [5,6,7,1,2,3,4]

Example 2:

	Input: [-1,-100,3,99] and k = 2
	Output: [3,99,-1,-100]
	Explanation: 
	rotate 1 steps to the right: [99,-1,-100,3]
	rotate 2 steps to the right: [3,99,-1,-100]

Note:
Try to come up as many solutions as you can, there are at least 3 different ways to solve this problem.
Could you do it in-place with O(1) extra space?

3、我的解法

方法一:借助JavaScript函数:slice、splice、unshift

	/**
	 * @param {number[]} nums
	 * @param {number} k
	 * @return {void} Do not return anything, modify nums in-place instead.
	 */
	var rotate = function(nums, k) {
	    
	    const tempArr = nums.slice(nums.length-k);  
	    
	    nums.splice(nums.length-k, k)
	    nums.unshift(...tempArr); 
	    
	    return nums;
	};		

在这里插入图片描述
方法二:暴力破解,循环遍历,按位右移一位

	/**
	 * @param {number[]} nums
	 * @param {number} k
	 * @return {void} Do not return anything, modify nums in-place instead.
	 */
	var rotate = function(nums, k) {
	    if(nums.length > 1) {     
	        for(let i = 0; i < k; i++) {
	            
	            let tempEnd = nums[nums.length-1];
	            for(let j = nums.length-1; j >= 0; j--) {
	                nums[j] = j > 0 ? nums[j-1] : tempEnd;                 
	            }
	            
	        }        
	    }
	    // return nums;
	};

在这里插入图片描述

4、其他的解法

方法三:单次循环遍历nums,按位右移K位
这个方法我有想到,但是在取余公式这里卡住,学习到了;

	/**
	 * @param {number[]} nums
	 * @param {number} k
	 * @return {void} Do not return anything, modify nums in-place instead.
	 */
	var rotate = function(nums, k) {
	    let newArr = [];
	    for(let i = 0; i < nums.length; i++) {
	        newArr[(i+k) % nums.length] = nums[i];
	    }
	    for(let j = 0; j < nums.length; j++) {
	        nums[j] = newArr[j];
	    }
	};

在这里插入图片描述
方法四:单次循环遍历nums,跳跃移动K位

	/**
	 * @param {number[]} nums
	 * @param {number} k
	 * @return {void} Do not return anything, modify nums in-place instead.
	 */
	var rotate = function(nums, k) {					
	    k = k % nums.length;  			// 注意对 k 的处理
	    let count = 0;
	    for(let i = 0; count < nums.length; i++) {
	        let current = i;        
	        let prev = nums[i];
	        
	        do {         
	            let next = (current+k)%nums.length;
	            let temp = nums[next];
	            nums[next] = prev;
	            prev = temp;
	            current = next;
	            count++;
	        } while (current != i);
	    }
	};

这个算法很好理解,但是实现起来有点纠结,因为需要设置几个中间变量。不过的确省去了方法三重新拷贝数组的时间,所以时间复杂度相对小一点,也不需要一个新的数组来保存数据;
在这里插入图片描述在这里插入图片描述
方法五:反转数组
这个反转数组的方法有点线性代数运算的感觉,而且时间复杂度是O(n),空间复杂度是O(1),可以说效率相对较高。

	/**
	 * @param {number[]} nums
	 * @param {number} k
	 * @return {void} Do not return anything, modify nums in-place instead.
	 */
	function reverse(nums, start, end) {
	    while(start < end) {
	        let temp = nums[start];
	        nums[start] = nums[end];
	        nums[end] = temp;
	        start++;
	        end--;
	    }
	}
	
	var rotate = function(nums, k) {
	    k = k % nums.length;
	    reverse(nums, 0, nums.length - 1);
	    reverse(nums, 0, k - 1);
	    reverse(nums, k, nums.length - 1);    
	};

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值