LeetCode #189 旋转数组

题目

暴力法

旋转 k k k次,每次将数组旋转1个元素。

C++代码

class Solution {
public:
    void rotate(vector<int>& nums, int k) {
        int len = nums.size();
        for(int i = 0;i < k;i++)
        {
            int temp = nums[len - 1];
            for(int j = len - 1;j > 0;j--)
            {
                nums[j] = nums[j - 1];
            }
            nums[0] = temp;               
        }
    }
};

复杂度分析

  • 时间复杂度: O ( n ∗ k ) O(n*k) O(nk)。每个元素都被移动 1 步 ( O ( n ) ) (O(n)) O(n) k k k ( O ( k ) ) (O(k)) O(k)
  • 空间复杂度: O ( 1 ) O(1) O(1) 。没有额外空间被使用。

下面是两种巧妙的官方题解方法。

环状替换法

直接把每一个数字放到它最后的位置,但这样的后果是遗失原来的元素。因此,需要把被替换的数字保存在变量 t e m p temp temp里面。然后,将被替换数字( t e m p temp temp)放到它正确的位置,并继续这个过程 n n n次, n n n是数组的长度。同时注意:如果 k k k大于 n n n,移动 k k k次实际上相当于移动 k % n k\%n k%n次。

下面是一个例子:

nums: [1, 2, 3, 4, 5, 6]
k: 2

在这里插入图片描述

C++代码

class Solution {
public:
    void rotate(vector<int>& nums, int k) {
        int len = nums.size();
        k = k % len;
        int count = 0;
        for (int start = 0; count < len; start++) {
            int current = start;
            int prev = nums[start];
            do {
                int next = (current + k) % len;
                int temp = nums[next];
                nums[next] = prev;
                prev = temp;
                current = next;
                count++;
            } while (start != current);
        }
    }
};

复杂度分析

  • 时间复杂度: O ( n ) O(n) O(n) 。只遍历了每个元素一次。
  • 空间复杂度: O ( 1 ) O(1) O(1) 。使用了常数个额外空间。

反转法

当旋转数组 k k k次, k % n k\%n k%n个尾部元素会被移动到头部,剩下的元素会被向后移动。

在这个方法中,首先将所有元素反转。然后反转前 k k k个元素,再反转后面 n − k n-k nk个元素,就能得到想要的结果。

假设 n = 7 n=7 n=7 k = 3 k=3 k=3

原始数组                  : 1 2 3 4 5 6 7
反转所有数字后             : 7 6 5 4 3 2 1
反转前 k 个数字后          : 5 6 7 4 3 2 1
反转后 n-k 个数字后        : 5 6 7 1 2 3 4 --> 结果

C++代码

class Solution {
public:
    void rotate(vector<int>& nums, int k) {
        int len = nums.size();
        k %= len;
        reverse(nums, 0, len - 1);
        reverse(nums, 0, k - 1);
        reverse(nums, k, len - 1);
    }
    void reverse(vector<int>& nums, int start, int end) {
        while (start < end) {
            int temp = nums[start];
            nums[start] = nums[end];
            nums[end] = temp;
            start++;
            end--;
        }
    }
};

复杂度分析

  • 时间复杂度: O ( n ) O(n) O(n)
  • 空间复杂度: O ( 1 ) O(1) O(1)

链接:https://leetcode-cn.com/problems/rotate-array/solution/xuan-zhuan-shu-zu-by-leetcode/
来源:力扣(LeetCode)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值