当前位置:   article > 正文

【数组】轮转数组

轮转数组

题目描述

给你一个数组,将数组中的元素向右轮转 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个方案我都能想到,但是在耗时方面都不是最好的;第三个方案,思路巧妙,代码实现简单,但我自己却没有想到。如果有更好的方案,欢迎回复。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/767079
推荐阅读
相关标签
  

闽ICP备14008679号