面试经典算法题38-轮转数组
LeetCode.189
公众号:阿Q技术站
问题描述
给定一个整数数组 nums
,将数组中的元素向右轮转 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]
示例 2:
输入:nums = [-1,-100,3,99], k = 2
输出:[3,99,-1,-100]
解释:
向右轮转 1 步: [99,-1,-100,3]
向右轮转 2 步: [3,99,-1,-100]
提示:
1 <= nums.length <= 105
-231 <= nums[i] <= 231 - 1
0 <= k <= 105
思路
-
处理
k
大于数组长度的情况,因为旋转一个长度为n
的数组n
次,得到的结果和原数组相同。 -
可以通过三次翻转实现数组的旋转。首先,将整个数组翻转;然后,将前
k
个元素翻转;最后,将剩余的元素翻转。
图解
+-----------------------------------------+
| 开始执行程序 |
+-----------------------------------------+
|
v
+-----------------------------------------+
| 输入: nums = [1,2,3,4,5,6,7], k = 3 |
+-----------------------------------------+
|
v
+-----------------------------------------+
| 处理 k 大于数组长度的情况 |
| k %= 7,得到 k = 3 |
+-----------------------------------------+
|
v
+-----------------------------------------+
| 定义反转数组的函数 reverse() |
+-----------------------------------------+
|
v
+-----------------------------------------+
| 定义反转部分数组的函数 |
| reverse(nums.begin(), nums.begin() + k) |
+-----------------------------------------+
|
v
+-----------------------------------------+
| 定义反转剩余部分数组的函数 |
| reverse(nums.begin() + k, nums.end()) |
+-----------------------------------------+
|
v
+-----------------------------------------+
| 打印当前数组状态 |
| [1,2,3,4,5,6,7] |
+-----------------------------------------+
|
v
+-----------------------------------------+
| 调用 reverse() 反转整个数组 |
| [7,6,5,4,3,2,1] |
+-----------------------------------------+
|
v
+-----------------------------------------+
| 打印当前数组状态 |
| [7,6,5,4,3,2,1] |
+-----------------------------------------+
|
v
+-----------------------------------------+
| 调用 reverse() 反转前 k 个元素 |
| [5,6,7,4,3,2,1] |
+-----------------------------------------+
|
v
+-----------------------------------------+
| 打印当前数组状态 |
| [5,6,7,4,3,2,1] |
+-----------------------------------------+
|
v
+-----------------------------------------+
| 调用 reverse() 反转剩余元素 |
| [5,6,7,1,2,3,4] |
+-----------------------------------------+
|
v
+-----------------------------------------+
| 打印当前数组状态 |
| [5,6,7,1,2,3,4] |
+-----------------------------------------+
|
v
+-----------------------------------------+
| 返回结果 |
+-----------------------------------------+
参考代码
C++
#include <iostream>
#include <vector>
using namespace std;
class Solution {
public:
void rotate(vector<int>& nums, int k) {
int n = nums.size();
k %= n; // 处理 k 大于数组长度的情况
if (k == 0) return; // 如果 k 等于 0,直接返回
// 翻转整个数组
reverse(nums.begin(), nums.end());
// 翻转前 k 个元素
reverse(nums.begin(), nums.begin() + k);
// 翻转剩余元素
reverse(nums.begin() + k, nums.end());
}
};
int main() {
vector<int> nums = {1, 2, 3, 4, 5, 6, 7}; // 输入数组
int k = 3; // 向右轮转的位置数
Solution solution;
solution.rotate(nums, k); // 调用 rotate 方法
cout << "旋转后的数组:";
for (int num : nums) {
cout << num << " ";
}
cout << endl;
return 0;
}
Java
import java.util.Arrays;
class Solution {
public void rotate(int[] nums, int k) {
int n = nums.length;
k %= n; // 处理 k 大于数组长度的情况
if (k == 0) return; // 如果 k 等于 0,直接返回
// 翻转整个数组
reverse(nums, 0, n - 1);
// 翻转前 k 个元素
reverse(nums, 0, k - 1);
// 翻转剩余元素
reverse(nums, k, n - 1);
}
private void reverse(int[] nums, int start, int end) {
while (start < end) {
int temp = nums[start];
nums[start] = nums[end];
nums[end] = temp;
start++;
end--;
}
}
public static void main(String[] args) {
int[] nums = {1, 2, 3, 4, 5, 6, 7}; // 输入数组
int k = 3; // 向右轮转的位置数
Solution solution = new Solution();
solution.rotate(nums, k); // 调用 rotate 方法
System.out.print("旋转后的数组:");
for (int num : nums) {
System.out.print(num + " ");
}
System.out.println();
}
}
Python
class Solution:
def rotate(self, nums: List[int], k: int) -> None:
n = len(nums)
k %= n # 处理 k 大于数组长度的情况
if k == 0:
return # 如果 k 等于 0,直接返回
# 翻转整个数组
self.reverse(nums, 0, n - 1)
# 翻转前 k 个元素
self.reverse(nums, 0, k - 1)
# 翻转剩余元素
self.reverse(nums, k, n - 1)
def reverse(self, nums: List[int], start: int, end: int) -> None:
while start < end:
nums[start], nums[end] = nums[end], nums[start]
start += 1
end -= 1
if __name__ == "__main__":
nums = [1, 2, 3, 4, 5, 6, 7] # 输入数组
k = 3 # 向右轮转的位置数
solution = Solution()
solution.rotate(nums, k) # 调用 rotate 方法
print("旋转后的数组:", nums)