📜  门| GATE CS 2021 |套装2 |问题5(1)

📅  最后修改于: 2023-12-03 15:42:12.656000             🧑  作者: Mango

GATE CS 2021 套装2 问题5

这个问题要求你实现一个名为 rotate_array 的函数,将一个长度为n的数组里的所有元素向右移动k位。在这个函数中,不可以新建另一个数组。

函数签名
def rotate_array(arr: List[int], k: int) -> None:
    pass

函数接受两个参数:

  • arr表示要旋转的数组,其中元素的长度为n。(1 <= n <= 10^4,0 <= arr[i] <= 10^3)
  • k表示旋转的幅度,即元素向右移动的位数。(0 <= k <= 10^4)

函数没有返回值,但是会修改原数组。

解题思路

我们可以使用三次反转操作完成这个题目。假设数组为 arr,长度为 n,移动的幅度为 k

  1. arr[0:n-k-1] 执行一次反转操作。
  2. arr[n-k:n-1] 执行一次反转操作。
  3. 对整个数组 arr 执行一次反转操作。

这三次反转操作可以将所有的元素向右移动k位。

代码实现
from typing import List

def reverse(arr: List[int], start: int, end: int) -> None:
    while start < end:
        arr[start], arr[end] = arr[end], arr[start]
        start += 1
        end -= 1

def rotate_array(arr: List[int], k: int) -> None:
    n = len(arr)
    k %= n
    # 反转前半部分
    reverse(arr, 0, n-k-1)
    # 反转后半部分
    reverse(arr, n-k, n-1)
    # 反转整个数组
    reverse(arr, 0, n-1)

我们先定义了一个名为 reverse 的函数,用于反转数组中的一段区间。然后在 rotate_array 函数中,我们对输入的数组进行了三次反转操作。

时间复杂度是O(n),空间复杂度是O(1)。

测试

我们可以使用下面的代码进行单元测试:

def test_rotate_array():
    arr = [1, 2, 3, 4, 5]
    k = 3
    rotate_array(arr, k)
    assert arr == [3, 4, 5, 1, 2]

    arr = [1, 2, 3, 4, 5]
    k = 8
    rotate_array(arr, k)
    assert arr == [3, 4, 5, 1, 2]

    arr = [1, 2, 3, 4, 5]
    k = 0
    rotate_array(arr, k)
    assert arr == [1, 2, 3, 4, 5]

    arr = [1, 2, 3, 4, 5]
    k = 5
    rotate_array(arr, k)
    assert arr == [1, 2, 3, 4, 5]
    
    arr = [1, 2, 3, 4, 5]
    k = 1
    rotate_array(arr, k)
    assert arr == [5, 1, 2, 3, 4]

    print("所有测试用例都通过了!")

test_rotate_array()

运行后,如果没有抛出异常,则说明所有测试用例都通过了。