每日一题:Leetcode-189 轮转数组

力扣题目

解题思路

java代码

力扣题目:

给定一个整数数组 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]

解题思路:

算法原理
这道题提供了两种旋转数组的方法。

方法一(rotate1)

  1. 创建一个与原始数组长度相同的新数组 newArr 。
  2. 通过计算 (i + k) % n 确定原始数组中每个元素在新数组中的位置,并将其复制到新数组的对应位置。
  3. 最后将新数组的内容复制回原始数组。

方法二(rotate2)

  1. 首先计算 k 对数组长度取模,以避免 k 大于数组长度的情况。
  2. 计算 k 和数组长度的最大公约数 count 。
  3. 从 0 到 count - 1 ,对于每个起始位置 start ,进行循环交换操作,直到回到起始位置。

代码分析

  • 在 rotate1 方法中,使用简单的数学计算确定新位置,并复制元素。
  • rotate2 方法中,通过最大公约数确定循环交换的分组数量,然后在每个分组内进行元素交换。
  • gcd 方法使用递归计算两个数的最大公约数。

时间复杂度

  • rotate1 方法的时间复杂度为  ,因为需要遍历数组两次(复制到新数组和从新数组复制回原数组)。
  • rotate2 方法的时间复杂度也为  ,其中外层循环的次数为最大公约数 count ,内层循环的次数与分组内的元素数量有关,总体来说也是与数组长度 n 成正比。

空间复杂度

  • rotate1 方法的空间复杂度为  ,因为创建了一个新的数组。
  • rotate2 方法的空间复杂度为  ,只使用了固定的几个变量,没有额外的数组空间分配。

java代码:

package com.example.myapplication;

public class Leetcode189 {
    public void rotate1(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);
    }
    public void rotate2(int[] nums, int k) {
        int n = nums.length;
        k = k % n;
        int count = gcd(k, n);
        for (int start = 0; start < count; ++start) {
            int current = start;
            int prev = nums[start];
            do {
                int next = (current + k) % n;
                int temp = nums[next];
                nums[next] = prev;
                prev = temp;
                current = next;
            } while (start != current);
        }
    }

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

    public static void main(String[] args) {
        Leetcode189 leetcode189 = new Leetcode189();
        int[] nums = new int[]{1, 2, 3, 4, 5, 6, 7};
        leetcode189.rotate2(nums, 3);
        for (int i : nums) {
            System.out.println(i);
        }
        leetcode189.rotate1(nums, 3);
        for (int i : nums) {
            System.out.println(i);
        }
    }
}

更多详细内容同步到公众号,感谢大家的支持!

每天都会给刷算法的小伙伴推送明日一题,并且没有任何收费项

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

L.2626

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值