leetcode算法14-轮转数组

题目:

给定一个整数数组 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:引入临时数组

代码:

class Solution {
    public void rotate(int[] nums, int k) {
        int length = nums.length;
        k = k % length; // 如果 k 大于数组长度,取模可以避免不必要的轮转
        int[] temp = new int[k]; // 创建一个临时数组来存储最后 k 个元素

        // 将最后 k 个元素存储到临时数组中
        for (int i = 0; i < k; i++) {
            temp[i] = nums[length - k + i];
        }

        // 将原数组前面的元素向右移动 k 个位置
        for (int i = length - 1; i >= k; i--) {
            nums[i] = nums[i - k];
        }

        // 将临时数组中的元素放到原数组的前面
        for (int i = 0; i < k; i++) {
            nums[i] = temp[i];
        }
    }
}

关键点:

思路:直接定义一个新数组,把后半部分超出索引的数据存起来。前面的移动覆盖后面。最终把临时数组的值赋值给原数组前面。

官方代码:

class Solution {
    public void rotate(int[] nums, int k) {
        int n = nums.length;
        int[] newArr = new int[n];
        for (int i = 0; i < n; ++i) {
            newArr[(i + k) % n] = nums[i];
        }
        System.arraycopy(newArr, 0, nums, 0, n);
    }
}

关键点:

1.思路:定义一个大小完全相同的数组。使用取模的方法把小于n的数组值移动,大于你的取模放前面。最终全额赋值回去。

2.关键api:

System.arraycopy(newArr, 0, nums, 0, n);
  • 使用 System.arraycopy 方法将临时数组 newArr 的内容复制回原数组 nums

  • System.arraycopy(src, srcPos, dest, destPos, length) 的作用是从源数组 src 的位置 srcPos 开始,复制 length 个元素到目标数组 dest 的位置 destPos

  • 在这里,srcnewArrsrcPos0destnumsdestPos0lengthn,表示将整个 newArr 复制到 nums

解法2:翻转+交换

代码:

class Solution {
    public void rotate(int[] nums, int k) {
        k %= nums.length;
        reverse(nums, 0, nums.length - 1);
        reverse(nums, 0, k - 1);
        reverse(nums, k, nums.length - 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 += 1;
            end -= 1;
        }
    }
}

关键点:

思路:力扣题解

该方法基于如下的事实:当我们将数组的元素向右移动 k 次后,尾部 kmodn 个元素会移动至数组头部,其余元素向后移动 kmodn 个位置。

该方法为数组的翻转:我们可以先将所有元素翻转,这样尾部的 kmodn 个元素就被移至数组头部,然后我们再翻转 [0,kmodn−1] 区间的元素和 [kmodn,n−1] 区间的元素即能得到最后的答案。

我们以 n=7,k=3 为例进行如下展示:

操作    结果
原始数组    1 2 3 4 5 6 7
翻转所有元素    7 6 5 4 3 2 1
翻转 [0,kmodn−1] 区间的元素    5 6 7 4 3 2 1
翻转 [kmodn,n−1] 区间的元素    5 6 7 1 2 3 4

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值