Leetcode刷题记录(5):189旋转数组

刷题网站:Leetcode

难度: 中等

语言: Python

计划:从简单——>到中等——>再到难。

一、189旋转数组

1.1 题目:

给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数。

  • 进阶
    尽可能想出更多的解决方案,至少有三种不同的方法可以解决这个问题。
    你可以使用空间复杂度为 O(1) 的 原地 算法解决这个问题吗?

  • 示例1

输入: nums = [1,2,3,4,5,6,7], k = 3
输出: [5,6,7,1,2,3,4]
解释:
向右旋转 1: [7,1,2,3,4,5,6]
向右旋转 2: [6,7,1,2,3,4,5]
向右旋转 3: [5,6,7,1,2,3,4]
  • 示例2
输入:nums = [-1,-100,3,99], k = 2
输出:[3,99,-1,-100]
解释: 
向右旋转 1: [99,-1,-100,3]
向右旋转 2: [3,99,-1,-100]

1.2 思考分析

初看本题,题目很短,但是难度是中等难度,所以还需重视。先理解题目大概意思,即给定一个数组和k值,然后把最后k个值放到前面来,形成一个新的数组输出。

首先,我想的是以k为切分,将数组分成了两部分,然后替换前后两部分的顺序即可。也就是将数组中第n-k个索引位置,挪到第0个索引位置,然后再将第n-k+1个索引位置,挪到第1个索引位置,以此类推,直至到最后一个。但同时也要将前面的第0个索引位置,挪到第k个索引位置,第1个索引位置,挪到第k+1个索引位置,以此类推,直至第n-k个位置。

但是,我们会发现一个问题,就是索引位置值的替换会有重复的,即当替换一个索引位置后,到后面可能重复替换了,所以我想先假设一个空数组,然后填充进去,而不是直接在原数组上替换。

故,完整代码如下(以下是我在Sublime text3上面运行的代码):

from typing import List
class Solution:
    def rotate(self, nums: List[int], k: int) -> None:
        """
        Do not return anything, modify nums in-place instead.
        """
        n = len(nums)
        nums2 = [1]*n
        i,j = 0,0
        m = k
        while m < n:
        	nums2[m] = nums[j]
        	if k>0:
        		nums2[i] = nums[n-k]
        		k-=1
        		i+=1
        	m+=1
        	j+=1
        return nums2
print(Solution().rotate([1,2,3,4,5,6,7],3))
print(Solution().rotate([-1,-100,3,99],2))

输出:

[5, 6, 7, 1, 2, 3, 4]
[3, 99, -1, -100]
[Finished in 0.1s]

初看结果,好像正确。但是,当我将代码输入到Leetcode执行的时候,竟然提示我错误,这就很纳闷,不知道错在哪里。在上面显示输出还是原数组,但是我笔算和计算机算都是正确的结果,为什么会错呢?
在这里插入图片描述
然后,根据代码中的提示

 """
 Do not return anything, modify nums in-place instead.
 """

提示不需要返回值,然后我把return删了,执行还是错误。

然后翻开评论,许多人也有我一样的问题,有的说是必须在原数组上修改,return没用,不知道怎么回事?

接着我们看题解的方法三,用到的思想是数组翻转

大概意思是:==先将所有元素翻转,尾部k mod n个元素就被移至数组头部(此处取模是因为题目给出的k可能大于n,其翻转k次要取模),然后再翻转[0, k mod n-1]区间的元素和[k mod n, n-1]区间的元素,即可。

由于python中的reverse()函数没有指定某前面几个数翻转(也可能是我不知道),故需要自己先定义一个翻转函数。

def reverse(self, nums):
	n = len(nums)-1
	i = 0
	while i<n:
		j = nums[i]
		nums[i] = nums[n]
		nums[n] = j
		i+=1
		n-=1
	return nums

然后再rotate()函数里调用它实施翻转,故完整代码如下:

class Solution:
    def rotate(self, nums: List[int], k: int) -> None:
        """
        Do not return anything, modify nums in-place instead.
        """
        k %=len(nums) 
        self.nums = self.reverse(nums)
        self.nums[0:k] = self.reverse(nums[0:k])
        self.nums[k:] = self.reverse(nums[k:])
        print(nums)
    def reverse(self,nums):
    	n = len(nums) -1
    	i = 0
    	while i < n:
    		j = nums[i]
    		nums[i] = nums[n]
    		nums[n] = j
    		i+=1
    		n-=1
    	return nums

执行结果通过,如下
在这里插入图片描述
虽然通过,但是算法应该不是最佳的。

1.3 总结

想想此题其实本身不难,也能解答,但是要按照要求作答就比较难想。就比如我们之前的方法是可以进行翻转的,但是提交就会有问题,是因为我们没考虑运行内存问题,故最终只能按照题解中的算法思想来求解。

猜你喜欢

转载自blog.csdn.net/A33280000f/article/details/121176298