leetcode 面试经典 150 题(6/150) 189.轮转数组

160 阅读1分钟

题目描述

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

算法思路

三次反转法:通过三次局部反转实现数组的右旋操作,无需额外空间。

核心步骤

  1. 处理 k 值:对 k 取模数组长度 n,避免无效旋转。
  2. 全局反转:将整个数组元素顺序反转。
  3. 前 k 个反转:反转数组前 k 个元素。
  4. 剩余元素反转:反转数组从 k 到末尾的元素。

操作解析

  • 示例nums = [1,2,3,4,5,6,7], k=3
    • 反转整体 → [7,6,5,4,3,2,1]
    • 反转前3个 → [5,6,7,4,3,2,1]
    • 反转剩余 → [5,6,7,1,2,3,4]

复杂度分析

  • 时间复杂度:O(n),三次反转各遍历一次数组。
  • 空间复杂度:O(1),原地修改数组。

代码实现

func rotate(nums []int, k int) {
    n := len(nums)
    if n == 0 {
        return
    }
    k %= n
    reverse(nums)
    reverse(nums[:k])
    reverse(nums[k:])
}

func reverse(a []int) {
    for i, j := 0, len(a)-1; i < j; i, j = i+1, j-1 {
        a[i], a[j] = a[j], a[i]
    }
}

关键点

  • 取模操作k %= n 确保有效旋转次数。
  • 原地反转:三次反转均直接操作原数组,无需额外空间。
  • 切片处理:Go 语言中切片传递为引用,直接修改原数组。