LeetCode - 解题笔记 - 189 - Rotate Array

这篇博客探讨了如何在O(N)的时间复杂度内,使用不同的方法原地旋转数组。解决方案包括利用额外数组、状态变量以及数组翻转。每种方法都详细分析了其时间复杂度和空间复杂度,所有实现均确保了空间效率。博客提供了C++和Python两种语言的代码示例。
摘要由CSDN通过智能技术生成

Solution 1

题目中希望本题至少实现三种方法,其中一种就是直接暴力地使用一个额外的新数组保存临时结果,因此不表。

对上述方式进一步简化,我们可以通过一个状态变量来保存转换结果但是很快发现经过一定次数后,调换会形成一个循环,并且经过观察发现一共有 gcd(k,n)个这样的循环。

  • 时间复杂度: O ( N ) O(N) O(N),其中 N N N为输入数组的长度。所有的数字都要完成一次旋转,因此先行遍历一次
  • 空间复杂度: O ( 1 ) O(1) O(1),仅需要常数个状态量维护整个旋转过程
class Solution {
public:
    void rotate(vector<int>& nums, int k) {
        // 首先确定总的遍历起始偏移量:gcd(k, n)
        int len = nums.size();
        int offset = gcd(k, len);
        
        // 逐个循环的遍历完成旋转
        for (int i = 0; i < offset; ++i) {
            int temp = i;
            int tempVal = nums[temp];
            do {
                int next = (temp + k) % len;
                swap(nums[next], tempVal);
                temp = next;
            } while (temp != i);
        }
    }
};

Solution 2

【参考官方题解】

一个简单的但有意思的规律:

给定指定的旋转量k,那么可以通过翻转整个数组→按照 k mod n 进行切分分别进行翻转完成旋转。需要做的就是实现一个in-place的翻转函数。

  • 时间复杂度: O ( N ) O(N) O(N),其中 N N N为输入数组的长度。所有的数字都要完成两次翻转
  • 空间复杂度: O ( 1 ) O(1) O(1),仅需要常数个状态量维护整个翻转过程
class Solution {
public:
    void rotate(vector<int>& nums, int k) {
        int len = nums.size();
        int offset = k % len;
        // cout << offset << endl;
        
        reverse(nums, 0, len - 1);
        reverse(nums, 0, offset - 1);
        reverse(nums, offset, len - 1);
    }
    
private:
    void reverse(vector<int> & nums, int start, int end) {
        while (start < end) {
            swap(nums[start], nums[end]);
            start++;
            end--;
        }
    }
};

Solution 3

Solution 1的Python实现

class Solution:
    def rotate(self, nums: List[int], k: int) -> None:
        """
        Do not return anything, modify nums in-place instead.
        """
        length = len(nums)
        offset = gcd(k, length)
        
        for i in range(offset):
            temp, tempVal = i, nums[i]
            # print(temp, tempVal)
            while True:
                new = (temp + k) % length
                nums[new], tempVal = tempVal, nums[new]
                temp = new
                # print(temp)
                if temp == i: break

Solution 4

Solution 2的Python实现

class Solution:
    def rotate(self, nums: List[int], k: int) -> None:
        """
        Do not return anything, modify nums in-place instead.
        """
        def reverse(start, end):
            nonlocal nums
            while start < end:
                nums[start], nums[end] = nums[end], nums[start]
                start += 1
                end -= 1
                
        length = len(nums)
        offset = k % length
        
        reverse(0, length - 1)
        reverse(0, offset - 1)
        reverse(offset, length - 1)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值