题目链接:189. 轮转数组 - 力扣(LeetCode)

题目描述:

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

示例 1:

输入: nums = [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]

示例 2:

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

提示:

  • 1 <= nums.length <= 105
  • -231 <= nums[i] <= 231 - 1
  • 0 <= k <= 105

进阶:

  • 尽可能想出更多的解决方案,至少有 三种 不同的方法可以解决这个问题。
  • 你可以使用空间复杂度为 O(1) 的 原地 算法解决这个问题吗?

思路一:

        由于大于i+k可能大于n,会排到-(n-i-k)的位置,不难想到(i+k)%n

代码:

class Solution {
        public void rotate(int[] nums, int k) {

            int n = nums.length;

            int[] ints = new int[n];

            for (int i = 0; i < n; i++) {
                ints[(i+k)%n]=nums[i];
            }

            System.arraycopy(ints, 0, nums, 0, n);

        }
    }

思路二:

        通过思路一我们思考可以发现其实把k和n-k的位置全部调换就是反着的答案,最进行一次反转即可。

代码:

class Solution {

        public void rotate(int[] nums, int k) {

            int n = nums.length;
            k=k%n;
            reverse(nums,0,n-1);
            reverse(nums,0,k-1);
            reverse(nums,k,n-1);

        }

        private 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 的最大公约数确定数组被拆分的独立环状分组数,然后对每个环从起始位置开始,按(当前索引+k)%n的规则循环替换元素位置,最终在 O (1) 额外空间下完成数组的原地右旋转。

代码:

class Solution {

        public void rotate(int[] nums, int k) {

         int n=nums.length;
         k = k % n;
         int cnt = gcd(k,n);

         for(int i=0;i<cnt;i++){

             int iP = i;
             int tP = nums[iP];

             do{
                 int next = (iP+k)%n;
                 int temp = nums[next];
                 nums[next]=tP;
                 tP=temp;
                 iP=next;
             }while (i!=iP);

         }

        }

        private int gcd(int x,int y){
            return y>0?gcd(y,x%y):x;
        }

    }

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐