三次反转法比较简单,我想的是怎么才能用一般的循环移位法,同时又不开新数组,用O(1)的空间来循环移位。
思路想的很快,把i位移动到(i+k)%n位,然后不移动i+1位,而是直接移动((i+k)%n+k)%n位,依次类推。
[1, 2, 1, 4, 5, 6]
[1, 2, 1, 4, 3, 6]
[5, 2, 1, 4, 3, 6]
[5, 2, 1, 2, 3, 6]
[5, 2, 1, 2, 3, 4]
[5, 6, 1, 2, 3, 4]
但是代码实现的时候纠结了很久,for循环里怎样的顺序才能保证不覆盖之前的数据?这里一个变量保存不够的,需要两个。
一个是覆盖前pre,一个是覆盖后cur。
代码如下:
import java.util.Arrays;
import java.util.ArrayList;
import java.util.List;
class Solution {
public void rotate(int[] nums, int k) { //循环右移法
int n = nums.length;
int index = 0;
int start = 0;
int pre = nums[index];
int cur ;
for(int i = 0; i< n; i++)
{
cur = pre;
pre = nums[(index +k )%n];
nums[(index + k)%n] = cur;
index = (index + k)%n;
if(index == start)
{
start++;
index = start;
pre = nums[index];
}
System.out.println(Arrays.toString(nums));
}
}
}
public class first{
public static void main(String args[])
{
Solution solution = new Solution();
int[] array = {1,2,3,4,5,6};
solution.rotate(array, 2);
System.out.println(Arrays.toString(array));
}
}
同时还有一个地方需要注意:有可能会循环回到0位置,造成死循环,需要加一个判断条件,保证执行0的下一个位置。
对于这种纠结于循环体里执行顺序的,有一个比较直接的方法:
手动依次执行算法,根据执行流程确定语句的顺序,以及初始值的确定。