189.轮转数组,力扣

目录

题目

解题1:---》用链表解决-----》超时,解题失败

题解2:------》在题解一上做优化-------》7秒

题解3---》用一个数组解决---》1秒

题解4----》扩展,看题解---------》0秒

三步反转法:

步骤1:整体反转

[步骤2:反转前 k 个元素](#步骤2:反转前 k 个元素)

[步骤3:反转剩余 n-k 个元素](#步骤3:反转剩余 n-k 个元素)


题目

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

解题1:---》用链表解决-----》超时,解题失败

java 复制代码
   public static void rotate1(int[] nums, int k) {
        // 这部分是 O(n)
        LinkedList<Integer> list = new LinkedList<>();
        for (int i = 0; i < nums.length; i++) {
            list.add(nums[i]); // O(1) 添加到链表尾部
        }

         // 这部分是 O(k * n)
        for (int i = 0; i < k; i++) {
            Integer last = list.pollLast(); // O(1) - 移除尾部
            list.add(0, last); // O(n) - 添加到头部需要遍历链表
        }

        // 这部分是 O(n)
        for (int i = 0; i < nums.length; i++) {
            nums[i] = list.get(i); // O(i) - 链表随机访问需要遍历
        }
    }

题解2:------》在题解一上做优化-------》7秒

java 复制代码
    public static void rotate2(int[] nums, int k) {
        k = k % nums.length; // 优化:减少不必要的旋转
        if (k == 0) return;

        Deque<Integer> deque = new ArrayDeque<>();
        for (int num : nums) {
            deque.add(num); // O(1)
        }

        // 一次性旋转 k 次
        for (int i = 0; i < k; i++) {
            int last = deque.pollLast(); // O(1)
            deque.addFirst(last); // O(1) - ArrayDeque头部插入比LinkedList快
        }

        // 使用迭代器或直接索引复制,避免随机访问
        int index = 0;
        for (int num : deque) {
            nums[index++] = num; // O(1)
        }
    }

题解3---》用一个数组解决---》1秒

java 复制代码
    public static void rotate(int[] nums, int k) {
        k = k%nums.length;
        if(k==0) return;

        int[] arr=new int[nums.length];
        int j=0;
        for (int i = nums.length-k; i < nums.length && j<nums.length; i++) {
            arr[j++]=nums[i];
        }
        for (int i = 0; i < nums.length - k; i++) {
            arr[j++]=nums[i];
        }
        //就算这里改了nums的地址,但是原main里的没有改
//        nums=arr;
        int i=0;
        for (int n :arr) {
            nums[i++]=n;
        }
    }

题解4----》扩展,看题解---------》0秒

三步反转法:

步骤1:整体反转

[1,2,3,4,5,6,7][7,6,5,4,3,2,1]

将整个数组完全反转

步骤2:反转前 k 个元素

[7,6,5,4,3,2,1]

前 k 个元素(k=3):[7,6,5][5,6,7]

得到:[5,6,7,4,3,2,1]

步骤3:反转剩余 n-k 个元素

[5,6,7,4,3,2,1]

剩余元素:[4,3,2,1][1,2,3,4]

最终:[5,6,7,1,2,3,4]

java 复制代码
    public void rotate(int[] nums, int k) {
        int n = nums.length;
        k %= n; // 关键:处理 k > n 的情况

        // 1. 整体反转
        reverse(nums, 0, n - 1);
        // 2. 反转前 k 个
        reverse(nums, 0, k - 1);
        // 3. 反转剩余部分
        reverse(nums, k, n - 1);
    }

    private void reverse(int[] nums, int i, int j) {
        while (i < j) {
            int tmp = nums[i];
            nums[i++] = nums[j];
            nums[j--] = tmp;
        }
    }
相关推荐
草履虫建模10 小时前
力扣算法 1768. 交替合并字符串
java·开发语言·算法·leetcode·职场和发展·idea·基础
naruto_lnq12 小时前
分布式系统安全通信
开发语言·c++·算法
Jasmine_llq13 小时前
《P3157 [CQOI2011] 动态逆序对》
算法·cdq 分治·动态问题静态化+双向偏序统计·树状数组(高效统计元素大小关系·排序算法(预处理偏序和时间戳)·前缀和(合并单个贡献为总逆序对·动态问题静态化
爱吃rabbit的mq13 小时前
第09章:随机森林:集成学习的威力
算法·随机森林·集成学习
(❁´◡`❁)Jimmy(❁´◡`❁)14 小时前
Exgcd 学习笔记
笔记·学习·算法
YYuCChi14 小时前
代码随想录算法训练营第三十七天 | 52.携带研究材料(卡码网)、518.零钱兑换||、377.组合总和IV、57.爬楼梯(卡码网)
算法·动态规划
不能隔夜的咖喱15 小时前
牛客网刷题(2)
java·开发语言·算法
VT.馒头15 小时前
【力扣】2721. 并行执行异步函数
前端·javascript·算法·leetcode·typescript
进击的小头15 小时前
实战案例:51单片机低功耗场景下的简易滤波实现
c语言·单片机·算法·51单片机
咖丨喱16 小时前
IP校验和算法解析与实现
网络·tcp/ip·算法