leetcode旋转数组(有值得回顾的地方)

本文探讨了三种不同的数组旋转方法:暴力法、反转法和环状替换法。暴力法通过每次旋转一个位置逐步达到目标;反转法通过两次反转实现元素的正确移动;环状替换法利用双循环巧妙地完成了旋转。每种方法都有其独特思路,适用于不同场景。代码实现详尽,适合初学者理解算法思想。
摘要由CSDN通过智能技术生成

解题思路

暴力法
每次旋转1个位置, 旋转k次即为正确答案。
旋转的时候也是利用前驱结点来实现的, 前驱结点的更新也借助temp变量。
这里重点体会如何完成向后移动一次
目前阶段遇到题目不要钻牛角尖, 暴力法能解就暴力法。

代码

class Solution {
    public void rotate(int[] nums, int k) {
        int previous;
		int temp;
		for (int i = 0; i < k; i++) {
			previous = nums[nums.length-1];  //前驱结点初始为最后一个结点
			for (int j = 0; j < nums.length; j++) {
				temp = nums[j]; //先保存当前结点
				nums[j]=previous;
				previous=temp; //更新前驱结点
			}
		}
    }
}

反转法 很实用

这个方法基于这个事实:当我们旋转数组 k 次,k%n 个尾部元素会被移动到头部, 剩下的元素依次向后移动。
1、反转可以把k%n个元素先放到前面,只需要对数组进行 0到k-1范围内的反转就可以得到想要的顺序
2、反转剩下的k-1到n-1个元素即实现了元素依次后移
3、前往要主义此处的k有可能超出数组长度,而如果恰等于数组长度就等于没变所以k=k%n

class Solution {
    public void rotate(int[] nums, int k) {
		int n = nums.length;  
        k %= n; //k可能会查过数组长度造成错误
		//1、反转数组
		reverse(nums,0,n-1);
        //2、前k个反转,后n-k个反转
		reverse(nums,0,k-1);
		reverse(nums,k,n-1);
    }
    //反转数组 用这种写法可以方便的反转任意区间的数组 也很使用
	public void reverse(int[] nums, int start, int end) {
        while (start < end) {
            int temp = nums[start];
            nums[start] = nums[end];
            nums[end] = temp;
            start++;
            end--;
        }
    }
}

环状替换

想到了但是代码实现的时候遇到了当 n%k==0的时候死循环而想不到解决的办法
以下是leetcode提供的代码,巧妙的用了双循环循环解决了我不能解决的尴尬,核心代码都是一样的,外循环的此时必定是数组长度
用count来控制外循环次数,内循环一镜到底都是我没有想到的。在编码方面还有很大提高

public class Solution {
    public void rotate(int[] nums, int k) {
        k = k % nums.length;
        int count = 0;
        for (int start = 0; count < nums.length; start++) {
            int current = start;
            int prev = nums[start];
            do {
                int next = (current + k) % nums.length;
                int temp = nums[next];
                nums[next] = prev;
                prev = temp;
                current = next;
                count++;
            } while (start != current);
        }
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值