• 【数组】轮转数组


    题目描述

    给你一个数组,将数组中的元素向右轮转 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]

    解题思路

    题目要求提供多种解决方案,自己能想到的是方案1和方案2,并方案2调试很多次才能通过(不超时),方案3完全是看别人的解答分析后才提供出来的,但是方案3最巧妙耗时也最少。

    方案1:

    • 初始化 int n=nums.length;
    • 提前处理k,操作:k %= n;  这个是避免重复的计算;
    • 拷贝一个数组,int[] clone = Arrays.copyOf(nums, nums.length);
    • 在循环体中,对nums进行重新赋值操作,nums[i]=clone[(i-k+n)%n];
    1. import java.util.Arrays;
    2. class Solution5 {
    3. public void rotate(int[] nums, int k) {
    4. int[] clone = Arrays.copyOf(nums, nums.length);
    5. int n = nums.length;
    6. k %= n;
    7. for (int i = 0; i < nums.length; i++) {
    8. nums[i] = clone[(i - k + n) % n];
    9. }
    10. System.out.println(Arrays.toString(nums));
    11. }
    12. public static void main(String[] args) {
    13. Solution5 solution = new Solution5();
    14. solution.rotate(new int[]{1, 2, 3, 4, 5, 6, 7}, 3);
    15. }
    16. }

    方案2:

    这个方案重点就是不使用数组了,只需要部分变量就能完成整体的移动;这里通过图来分析:

    • 初始化阶段,准备index=0,value=1,k=3
    • 第一步,根据公式计算出index=(index+k)%nums.length, 找到要处理的index=3,执行nums[3]=1,value=4;
    • 第二步,根据公式计算出index=(index+k)%nums.length, 找到要处理的index=6,执行nums[6]=4,value=7;
    • 以此类推下去
    • 直到执行次数等于nums.length;其他case 考虑nums.length=6,k=3 的情况。

    得到下面的代码实现:

    1. class Solution4 {
    2. public void rotate(int[] nums, int k) {
    3. k %= nums.length;
    4. if (k == 0) {
    5. return;
    6. }
    7. int count = 0;
    8. for (int i = 0; i < k; i++) {
    9. int index = i;
    10. int start = index;
    11. int value = nums[index];
    12. while (true) {
    13. if (count >= nums.length) {
    14. break;
    15. }
    16. index += k;
    17. if (index >= nums.length) {
    18. index %= nums.length;
    19. }
    20. int temp = nums[index];
    21. nums[index] = value;
    22. value = temp;
    23. count++;
    24. if (start == index) {
    25. break;
    26. }
    27. }
    28. }
    29. }
    30. public static void main(String[] args) {
    31. Solution4 solution = new Solution4();
    32. solution.rotate(new int[]{1, 2, 3, 4, 5, 6}, 4);
    33. solution.rotate(new int[]{1, 2, 3, 4, 5, 6, 7}, 3);
    34. }
    35. }

    方案3:

    这个方案只需要3次操作,操作思路如下:

    • 准备一个reverse方法,主要是将现有数组做倒序操作;准备一个数组 int nums[] = new int[] {1,2,3,4,5,6,7}; int k = 3; 
    • 第一步,将所有数据进行reverse,nums = {7,6,5,4,3,2,1};
    • 第二步,将0到k-1的元素做reverse操作,nums = {5,6,7,4,3,2,1};
    • 第三步,将k到nums.length-1的元素做reverse操作,nums= {5,6,7,1,2,3,4};

    按照这个巧妙的思路代码如下:

    1. class Solution {
    2. public void rotate(int[] nums, int k) {
    3. k %= nums.length;
    4. reverse(nums, 0, nums.length - 1);
    5. reverse(nums, 0, k - 1);
    6. reverse(nums, k, nums.length - 1);
    7. }
    8. private void reverse(int[] nums, int start, int end) {
    9. while (start < end) {
    10. int temp = nums[start];
    11. nums[start] = nums[end];
    12. nums[end] = temp;
    13. ++start;
    14. --end;
    15. }
    16. }
    17. public static void main(String[] args) {
    18. Solution solution = new Solution();
    19. solution.rotate(new int[]{1, 2, 3, 4, 5, 6}, 4);
    20. solution.rotate(new int[]{1, 2, 3, 4, 5, 6, 7}, 3);
    21. }
    22. }

    总结

    这道题是一个要求有多种解决方案的问题,前2个方案我都能想到,但是在耗时方面都不是最好的;第三个方案,思路巧妙,代码实现简单,但我自己却没有想到。如果有更好的方案,欢迎回复。

  • 相关阅读:
    怎么快速提取图片中的文字信息?怎么使用OCR图片文字提取一键提取文字
    微软ADFS成本评估
    Docker实践经验:Docker 上部署 mysql8 主从复制
    S3 client向ceph上传文件注意事项
    latex图片在双栏文档中横跨两栏
    nginx配置ssl证书
    时代变了,199 美元的 iPhone 都可以想了?
    R语言ggplot2可视化:使用patchwork包将两个ggplot2可视化结果横向构成新的结果可视化组合图(使用|符号)
    关于Unity Time.deltaTime的理解和使用
    11-16 周四 简单代码理解FlashAttention 分块计算softmax
  • 原文地址:https://blog.csdn.net/weiliuhong1/article/details/126196954