当前位置:   article > 正文

力扣:旋转数组(c++)_力扣螺旋数组

力扣螺旋数组

题目:

给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数。

解:

思路:

关键点确定当前元素要去的位置。确定好要去的位置,将该位置上的元素备份(tag = 该位置的元素),然后替换成当前元素。此时被替换的位置变成了当前位置(否则被替换位置上的元素tag数据会丢失),且要进行移动的数为tag,继续进行要去的位置的查找然后替换。直到全部位置都被替换过。因为每个位置有且只有一次被替换,所以遍历总长度或者替换总次数应该=数组长度

0 -> 3   

3-> 6   

6-> 9  9>7(长度不足,回返)  故6 -> 2

2 ->5

5 ->8  8>7(长度不足,回返)  故5 -> 1

1 ->4

4 ->7  7=7(长度不足,因为从0开始,回返)   故 4 -> 0

全部元素被替换完成。

 

要去的位置 =  当前位置+跨越长度,共有两种情况:

1:要去的位置 <  数组长度

   根据余数的一个特点是 任何一个数除一个比本身大的数,余数为该数本身

   所以:要去的位置 = (当前位置+跨越长度)% (数组长度)

2:要去的位置 >  数组长度

   假设判断位置为 5 的元素要去的位置 5+3 = 8

   1-7已经走过一圈的长度, 但还有一格未走,因为是环形,又回到了初始的位置1上。如图所示在环形上5要走3格,到达的位置也为 1

   故:其余数为 回返之后的位置,该位置为要去的位置

                         

 

特殊情况:当要去的位置 > 数组长度,并且数组长度为跨越长度的倍数时,会导致第一次回返的数值为 0 ,但此时0已经作为起始点移动过,需要手动将要移动的数的位置+1,否则将会一直不能遍历完数组,陷入死循环。

代码:

  1. void rotate(vector<int>& nums, int k)
  2. {
  3. if (nums.size() < 2 || k == 0)
  4. return;
  5. int changenumnow = nums[0], changenumnext = nums[0], tag = 0;
  6. int j = 0; // j 为移动后的位置
  7. int count = 0; // 记录移动次数
  8. if (k >= nums.size())
  9. {
  10. k = k % nums.size();
  11. }
  12. while (count != nums.size())
  13. {
  14. j = (j + k) % nums.size();
  15. changenumnext = nums[j];
  16. nums[j] = changenumnow;
  17. count++;
  18. // 回返的第一个数必为0,第二个为1,以此类推
  19. // 先判断回返的数 == 0,确定为特殊情况,并将起始位置+1,变成1,此时1也作为起始位置替换过其他元素,再次回返为1 时,操作同==0
  20. if (j == tag && j != nums.size()-1) //处理数组长度为步长倍数的情况
  21. {
  22. j = j + 1;
  23. tag = tag + 1; // 对0 1 2 3... 元素作为起始位置做标记,用来判断是否做过起始位置替换别的元素
  24. changenumnext = nums[j];
  25. }
  26. changenumnow = changenumnext;
  27. }
  28. }

 

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

闽ICP备14008679号