面试经典算法题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 += 1end -= 1if __name__ == "__main__":nums = [1, 2, 3, 4, 5, 6, 7]  # 输入数组k = 3  # 向右轮转的位置数solution = Solution()solution.rotate(nums, k)  # 调用 rotate 方法print("旋转后的数组:", nums)