leetcode 189. Rotate Array (python)

·  阅读 706

「这是我参与2022首次更文挑战的第16天,活动详情查看:2022首次更文挑战

描述

Given an array, rotate the array to the right by k steps, where k is non-negative. Follow up:

  • Try to come up with as many solutions as you can. There are at least three different ways to solve this problem.
  • Could you do it in-place with O(1) extra space?

Example 1:

Input: nums = [1,2,3,4,5,6,7], k = 3
Output: [5,6,7,1,2,3,4]
Explanation:
rotate 1 steps to the right: [7,1,2,3,4,5,6]
rotate 2 steps to the right: [6,7,1,2,3,4,5]
rotate 3 steps to the right: [5,6,7,1,2,3,4]
复制代码

Example 2:

Input: nums = [-1,-100,3,99], k = 2
Output: [3,99,-1,-100]
Explanation: 
rotate 1 steps to the right: [99,-1,-100,3]
rotate 2 steps to the right: [3,99,-1,-100]
复制代码

Note:

1 <= nums.length <= 10^5
-2^31 <= nums[i] <= 2^31 - 1
0 <= k <= 10^5
复制代码

解析

根据题意,给定一个数组,将数组向右旋转 k 步,其中 k 为非负数。题目提出来更高的要求:

  • 尝试想出尽可能多的解决方案。 至少三种不同的方法可以解决这个问题
  • 用 O(1) 额外的空间就地完成

要想使用 O(1) 的额外空间,那就说说明只能在 nums 本身进行改动,我们最先想到的思路,就是很朴素的一种。按照题目的描述,我们是将 nums 看成一个圆,向右转了 k 个元素形成的结果,所以由上可知:

  • 直接进行 k 次的遍历
  • 每次遍历将 nums 的所有元素都向右移动一位
  • 执行完上述的操作得到的 nums 即为结果。

时间复杂度为 O(k*N) ,空间复杂度为 O(1) 。

解答

class Solution(object):
    def rotate(self, nums, k):
        """
        :type nums: List[int]
        :type k: int
        :rtype: None Do not return anything, modify nums in-place instead.
        """
        N = len(nums)
        k = k % N
        if k == 0 : return nums
        for _ in range(k):
            t = nums[-1]
            for i in range(N-1,0,-1):
                nums[i] = nums[i-1]
            nums[0] = t            	      
		
复制代码

运行结果

Time Limit Exceeded
复制代码

解析

其实就是将后面的 k 个元素进行逆向反转得到 t ,然后将 nums[:N-k] 赋值给 nums[k:] ,然后将 t 赋值给 nums[:k] 也是符合题意的操作,这种解法的空间复杂度为 O(1) ,时间复杂度为 O(N) 。

解答

class Solution(object):
    def rotate(self, nums, k):
        """
        :type nums: List[int]
        :type k: int
        :rtype: None Do not return anything, modify nums in-place instead.
        """
        N = len(nums)
        k = k % N
        if k == 0 : return nums
        t = nums[-k:]
        nums[k:] = nums[:N-k]
        nums[:k] = t
            
        
        
复制代码

运行结果

Runtime: 341 ms, faster than 11.28% of Python online submissions for Rotate Array.
Memory Usage: 25.1 MB, less than 39.85% of Python online submissions for Rotate Array.
复制代码

解析

其实这道题还可以使用一种反转的规律还进行解题,如下所示:

  • 最初的数组 nums 表示如下 : 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

所以我们定义一个 reverse 函数将上面的三个过程进行执行即可,需要注意的是 k 在这里要对 nums 的长度取模,因为 k 如果太大的时候只需要知道 k%len(nums) 是多少即可,中间很多次整数组的移动对于结果没有影响,不但增加计算量,还会使函数不能正确运行。

时间复杂度为 O(N) ,空间复杂度为 O(1) 。

解答

class Solution(object):
    def rotate(self, nums, k):
        """
        :type nums: List[int]
        :type k: int
        :rtype: None Do not return anything, modify nums in-place instead.
        """
        k %= len(nums)
        self.reverse(nums, 0, len(nums)-1)
        self.reverse(nums, 0, k-1)
        self.reverse(nums, k, len(nums)-1)
    
    def reverse(self, nums, start, end):
        while start<end:
            tmp = nums[start]
            nums[start] = nums[end]
            nums[end] = tmp
            start += 1
            end -= 1
复制代码

运行结果

Runtime: 267 ms, faster than 34.40% of Python online submissions for Rotate Array.
Memory Usage: 25.1 MB, less than 15.20% of Python online submissions for Rotate Array.
复制代码

原题链接

leetcode.com/problems/ro…

您的支持是我最大的动力

分类:
后端
收藏成功!
已添加到「」, 点击更改