​189. 旋转数组​

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

方法一:

三次数值的反转

第一次: revers(nums, 0, nums.length - 1); 7,6,5,4,3,2,1

第二次 revers(nums, 0, k - 1); 5,6,7,4,3,2,1

第三次 revers(nums, k, nums.length - 1); 5,6,7,1,2,3,4

public void rotate(int[] nums, int k) {
//元素向右移动 k 个位置
//在此与原数组的模 防止出界
k = k % nums.length;
revers(nums, 0, nums.length - 1);
revers(nums, 0, k - 1);
revers(nums, k, nums.length - 1);
}

private void revers(int[] nums, int start, int end) {
while (start < end) {
int temp = nums[start];
nums[start] = nums[end];
nums[end] = temp;
start++;
end--;
}
}

暴力

最简单的方法是旋转k次,每次将数组旋转一个元素

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

int temp = 0;
int pre = 0;
for (int j = 0; j < k; j++) {
pre = nums[nums.length - 1];
for (int i = 0; i < nums.length; i++) {
temp = nums[i];
nums[i] = pre;
pre = temp;
}
}

}

环状替代

思路

把元素看做同学,把下标看做座位,大家换座位。第一个同学离开座位去第k+1个座位,第k+1个座位的同学被挤出去了,他就去坐他后k个座位,如此反复。但是会出现一种情况,就是其中一个同学被挤开之后,坐到了第一个同学的位置(空位置,没人被挤出来),但是此时还有人没有调换位置,这样就顺着让第二个同学换位置。 那么什么时候就可以保证每个同学都换完了呢?n个同学,换n次,所以用一个count来计数即可。

LC189-旋转数组_leetcode

public static void rotate2(int[] nums, int k) {
k = k % nums.length;
int count = 0;//记录交换的次数 判断是否终止结束
for (int start = 0; count < nums.length; start++) {
int current=start;//现在需要交换的值下标
int prev=nums[start];//现在需要交换的值
do{
//保存被交换的下标位next
int next=(current+k)%nums.length;
//保存被交换的值
int temp=nums[next];
nums[next]=prev;//交换
prev=temp;//保存下一次交换的值
current=next;//下一次需要交换的坐标的
count++;//交换次数加一
//判断现在交换的值是否已经交换了.如已经交换,由右临开始
}while (start!=current);
}
System.out.println(Arrays.toString(nums));
}