使用环状替换 Leetcode189

Posted zhang-qi123

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用环状替换 Leetcode189相关的知识,希望对你有一定的参考价值。

使用环状替换 Leetcode189

一、题目

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

示例 1:

输入: [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:

输入: [-1,-100,3,99] 和 k = 2 输出: [3,99,-1,-100] 解释: 向右旋转 1 步: [99,-1,-100,3] 向右旋转 2 步: [3,99,-1,-100]

说明:

尽可能想出更多的解决方案,至少有三种不同的方法可以解决这个问题。
要求使用空间复杂度为 O(1) 的 原地 算法。

二、题解

思路:类似于让位子,有一个环形的座位,每个人跑到同一方向下距离自己k个位置的位置上,那么那个位置上的人同样需要跑到距离自己k个位置的位置上,直到所有的人都坐到了自己的后来的位置上。

那么在循环让位的过程中,只需要知道前一个人原来的值,保留自己原来的值,用前一个人原来的值覆盖当前的位置,把自己原来的值传给后来的位置,并且对已让位人数计数。

当nums是1,2,3,4,5,6,7 k=3时,

操作过程为:

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

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

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

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

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

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

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

这是一次循环刚好所有的数都让位完的情况

当然还有1,2,3,4 5,6 k=2时

1,2,3,4,5,6

这种情况只会奇数让奇数,偶数让偶数,一次循环是不够的

还需要再一次循环

1,2,3,4,5,6

因而在每次循环前要记录循环开头的位置,当循环到原来开头的位置时,说明这条链上所有能让的都已经让了,但是count<len说明当前还有人没有让完,因此需要从开头下一个位置开始再次循环,直到所有人都已让完。

class Solution {

  public void rotate(int[] nums, int k) {

?    int len=nums.length;

?    int begin=0;//每个循环的开头位置

?    int now;//记录当前位置

?    int count=0;//记录当前已让位的人数



?    while(count<len)

?    {

?      //循环替换,每一个数向后挪k位,当k>nums.length时,挪k%nums.length位

?      //当回到循环开头部分时,循环结束,以当前开头的下一个数来开头

?      int temp;

?      now=begin;

?      int pre=nums[begin];



?      do {

?        now = (now + k) % len;

?        count++;// 让位人数增加

?        temp = nums[now];// 保存当前位置原来的值

?        nums[now] = pre;

?        pre = temp;

?      } while (now != begin);

?      begin++;

?    }

  }

}

 

以上是关于使用环状替换 Leetcode189的主要内容,如果未能解决你的问题,请参考以下文章

leetcode189旋转数组

数组旋转 Leetcode#189

前端与算法 leetcode 189. 旋转数组

LeetCode:189. 旋转数组(python3)

LeetCode 189

leetcode 189. Rotate Array