给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数。
- 尽可能想出更多的解决方案,至少有三种不同的方法可以解决这个问题。
- 要求使用空间复杂度为 O(1) 的原地算法
考虑到空间复杂度为1,只有一个额外存储空间,一开始的想法是这样的
class Solution:
def rotate(self, nums: 'List[int]', k: 'int') -> 'None':
"""
Do not return anything, modify nums in-place instead.
"""
k%=len(nums)
while k:
k-=1
a=nums[-1]
for i in range(len(nums)-1,-1,-1):
nums[i]=nums[i-1]
nums[0]=a
时间复杂度为kn,这样超时了,看了下别人的方法后自己写成这样
class Solution:
def rotate(self, nums: 'List[int]', k: 'int') -> 'None':
"""
Do not return anything, modify nums in-place instead.
"""
k%=len(nums)
nums[:]=list(reversed(nums))
nums[0:k]=list(reversed(nums[0:k]))
nums[k:len(nums)]=list(reversed(nums[k:len(nums)]))
过是过了,但题目要求是空间O(1),list(reversed(nums))应该创建了新的list,然后使用nums[:]进行切片赋值
(
切片是个比较容易搞混的东西,经过研究,我总结出来
a[:]=[x,x,x]时,a的地址不变,a内容变成[x,x,x]
b=a[:]时,a[:]在右边,会进行浅拷贝,对b中元素的修改一般不影响a(浅拷贝,实际上有可能影响,参考https://www.cnblogs.com/wilber2013/p/4645353.html)
)
所以又有了如下修改
class Solution:
def rotate(self, nums: 'List[int]', k: 'int') -> 'None':
"""
Do not return anything, modify nums in-place instead.
"""
k%=len(nums)
nums.reverse()
for i in range(k//2):
nums[i],nums[k-1-i]=nums[k-1-i],nums[i]
for i in range(k,(len(nums)+k)//2):
nums[i],nums[len(nums)+k-1-i]=nums[len(nums)+k-1-i],nums[i]
以前写c语言的code,都是直接用swap(),python中a,b=b,a的用法感觉比较新颖,经查说是python中的赋值全部都是变量地址的赋值。
——>
C中变量有类型,代表一定内存。
而Python变量只是封装过的指针,没有类型。如果不指向对象,就没有意义,更谈不上类型。
python中 a=b,和C中 a=b是完全不同的两个操作。前者只是指针(引用)的赋值,而后者则完全是内存的复制。