轮转数组

1、题目描述

给定一个整数数组 nums,将数组中的元素向右轮转 k 个位置,其中 k 是非负数。
在这里插入图片描述

2、解答思路

2.1、辅助数组

如果我们在原数组上通过覆盖元素会导致部分元素的丢失,因此这里使用额外的数组用来保存轮转后的数组。由题意可得,长度为m的数组,轮转 k 后,数组元素下标 index 和之前的下标 i 关系是 index = (i+k) % m。得到上述关系即可解答问题。

class Solution {
    public void rotate(int[] nums, int k) {
        int m = nums.length;
        int[] ans = new int[m];
        for(int i=0; i<m; i++){
            // 求解当前下标元素复制到另一个数组的下标
            int index = (i+k)%m;
            ans[index] = nums[i];
        }

        // 将ans的元素从下标0开始复制m个元素到数组nums中
        System.arraycopy(ans, 0, nums, 0, m);
    }
}
  • 将数组ans复制到nums时出现的错误:我利用 nums = Arrays.copyOfRange(ans, 0, m+1) 来复制时得到的结果是错误的,这是因为 Arrays.copyOfRange()
    创建并返回了一个新的数组,因此赋值后的nums和之前的nums已经不是同一个数组了,而题目要求的是原来的nums轮转k个位置,因此出现了结果错误的情况。
  • 时间复杂度: O(n),其中 n 为数组的长度。
  • 空间复杂度: O(n),额外增加了长度为n的辅助数组。

2.2、原地反转

根据题意可得到结论:将长度为n的数组向右轮转k个位置时,首先反转整个数组,然后反转前k的元素,最后反转n-k个元素,得到的结果即为最终结果,如下图所示。
在这里插入图片描述

class Solution {
    public void rotate(int[] nums, int k) {
        int n = nums.length;
        k %= n; // 由于 k 可能大于 n ,因此轮转 k 次等于轮转 k%n 次
        reverse(nums, 0, n - 1);
        reverse(nums, 0, k - 1);
        reverse(nums, k, n - 1);
    }

    // 将数组 nums下标 i 到 j 的元素翻转
    private void reverse(int[] nums, int i, int j) {
        while (i < j) {
            int temp = nums[i];
            nums[i++] = nums[j];
            nums[j--] = temp;
        }
    }
}

  • 时间复杂度:O(n),其中 n 是 nums 的长度。
  • 空间复杂度:O(1),原地反转的方法不需要辅助数组,因此空间复杂度为O(1)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值