使用环状替换 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的主要内容,如果未能解决你的问题,请参考以下文章