侧边栏壁纸
博主头像
StarStone 博主等级

长风破浪会有时,直挂云帆济沧海

  • 累计撰写 31 篇文章
  • 累计创建 16 个标签
  • 累计收到 1 条评论

目 录CONTENT

文章目录

Leetcode 189. 轮转数组

StarStone
2024-01-29 / 0 评论 / 0 点赞 / 43 阅读 / 0 字

189. 轮转数组

189. 轮转数组

  • 标签:数组、数学、双指针

  • 难度:中等

描述:给定一个整数数组 nums和数字 k

要求:将数组中的元素向右轮转 k 个位置,其中 k 是非负数。

说明:

  • 1 <= nums.length <= 10^5

  • -2^31 <= nums[i] <= 2^31 - 1

  • 0 <= k <= 10^5

示例:

  • 示例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:使用额外数组

对结果进行分析,

  • k=1: [7,1,2,3,4,5,6]。k=1划分区间,左边区间是[1,2,3,4,5,6],右边区间是 [7]。最后结果是将左、右区间对换位置。下步同理。

  • k=2: [6,7,1,2,3,4,5]。k=2划分区间,左边区间是[1,2,3,4,5],右边区间是 [6,7]。

  • k=3: [5,6,7,1,2,3,4]。k=3划分区间,左边区间是[1,2,3,4],右边区间是 [5,6,7]。

所以新建1个数组array,array先保存原数组的右边的区间,然后再保存原数组左边的区间。最后,把原数组复制array,得到符合要求的结果。

public void rotate(int[] nums, int k) {
        int[] array = new int[nums.length];
        k = k % nums.length;
        int j = 0;
        for (int i = nums.length - k; i < nums.length; i++) {
                array[j++] = nums[i];
        }
        for (int i = 0; i < nums.length - k; i++) {
                array[j++] = nums[i];
        }
        for (int i = 0; i < nums.length; i++) {
                nums[i] = array[i];
        }
}

优化:右移过程 k 位实际是原数组下标为 i 的元素放至新数组下标为 (i+k) mod n 的位置

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

思路2:翻转数组

  • 现将数组全部翻转,此时后半段元素到了前部,前半段元素到了后部。不过元素的顺序是反着的。

  • 再将[0, k - 1]段元素翻转,元素就变成了正序。

  • 再将[k, n - 1]段元素翻转,元素就变为了正序。

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

操作

结果

原始数组

1 2 3 4 5 6 7

翻转所有元素

7 6 5 4 3 2 1

翻转 [0, (k mod n)−1]区间的元素

5 6 7 4 3 2 1

翻转 [k mod n, n−1] 区间的元素

5 6 7 1 2 3 4

public void rotate(int[] nums, int k) {
        int n = nums.length;
        k %= n;
        reverse(nums, 0, n - 1);
        reverse(nums, 0, k - 1);
        reverse(nums, k , n - 1);
}
public void reverse(int[] array, int start, int end){
        int temp;
        while (start < end){
                temp = array[start];
                array[start] = array[end];
                array[end] = temp;
                start++;
                end--;
        }
}

189.轮转数组 题解

0

评论区