0
点赞
收藏
分享

微信扫一扫

每日一题:【LeetCode 189】轮转数组

题目描述

给你一个数组,将数组中的元素向右轮转​k​​个位置,其中​k​​是非负数。

示例1:


输入: nums = [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]
输入: nums = [-1,-100,3,99], k = 2
输出: [3,99,-1,-100]
解释:
向右轮转 1 步: [99,-1,-100,3]
向右轮转 2 步: [3,99,-1,-100]

方法一:临时数组

通过找规律发现数组下标为​i​​的元素向右移动​k​​位,如果超过了数组长度,该元素会移动到到下标为​(i+k)%length​​的位置。

每日一题:【LeetCode 189】轮转数组_i++

class Solution {    
public void rotate(int[] nums, int k) {
int length = nums.length;
int temp[] = new int[length];
for(int i=0; i<nums.length; i++){
temp[i] = nums[i];
}
for(int i=0; i<nums.length; i++){
nums[(i+k)%length] = temp[i];
}
}
}


每日一题:【LeetCode 189】轮转数组_i++_02

甚至可以看成两个子数组整体的移位。

每日一题:【LeetCode 189】轮转数组_微信_03

class Solution {   
public void rotate(int[] nums, int k) {
k = k % nums.length;
int temp[] = new int[k];
int j = 0;
// 倒数k个元素存入临时数组中
for (int i = nums.length - k; i < nums.length; i++) {
temp[j++] = nums[i];
}
//0~k-1的元素后移k位
for (int i = nums.length - k - 1; i >= 0; i--) {
nums[i+k] = nums[i];
}
//将临时数组的中的元素存入原数组0~k
for (int i = 0; i < temp.length; i++) {
nums[i] = temp[i];
}
}
}

每日一题:【LeetCode 189】轮转数组_数组_04

该方法用Python编写更简洁。


class Solution:
def rotate(self, nums: List[int], k: int) -> None:
"""
Do not return anything, modify nums in-place instead.
"""
k %= len(nums)
nums[:] = nums[-k:] + nums[:-k]

每日一题:【LeetCode 189】轮转数组_数组_05

方法二:多次翻转

通过数组翻转的方法实现,先全部翻转,再翻转前​k​​个,最后翻转剩余部分。


每日一题:【LeetCode 189】轮转数组_i++_06


class Solution {
public void rotate(int[] nums, int k) {
int length = nums.length;
k = k %length;
reverse(nums, 0, length - 1); //先反转全部的元素
reverse(nums, 0, k - 1); //在反转前k个元素
reverse(nums, k, length - 1); //接着反转剩余的
}
//把数组中从[start, end]之间的元素两两交换
public void reverse(int[] nums, int start, int end) {
while (start < end) {
int temp = nums[start];
nums[start++] = nums[end];
nums[end--] = temp;
}
}
}

每日一题:【LeetCode 189】轮转数组_数组_07

这方法快的离谱。

方法三:环形旋转

把数组首位相连,看成一个环,依次后移。


每日一题:【LeetCode 189】轮转数组_微信_08

但这里要注意当数组长度是​​k​​的整数倍时,会出现无限循环。


每日一题:【LeetCode 189】轮转数组_微信_09

因此需要创建一个布尔类型数组统计每个元素是否被访问,如果被访问过,则从该元素的下一个元素开始。


class Solution {
public static void rotate(int[] nums, int k) {
int index = 0;
int hold = nums[0];
int length = nums.length;
boolean[] visited = new boolean[length];
for (int i = 0; i < length; i++) {
index = (index + k) % length;
if (visited[index]) {
//如果访问过,再次访问的话,会出现原地打转的现象,
//不能再访问当前元素了,我们直接从他的下一个元素开始
index = (index + 1) % length;
hold = nums[index];
i--;//这次不能算是有效移动,次数回退
} else {
//把当前值保存在下一个位置,保存之前要把下一个位置的
//值给记录下来
visited[index] = true;
int temp = nums[index];
nums[index] = hold;
hold = temp;
}
}
}
}

每日一题:【LeetCode 189】轮转数组_i++_10

举报

相关推荐

0 条评论