LeetCode刷题记录
2025.10.8开始刷题~记录一下过程中遇到的一些小问题
C++菜鸟选手转码中 所以一些语法问题也会被一起记录^-^
189. Rotate Array
Given an integer array nums, rotate the array to the right by k steps, where k is non-negative.
最初思路(并不符合考点)
python
class Solution(object):
def rotate(self, nums, k):
n=len(nums)
nums1=[None]*n
k=k%n
cnt=0
if k==0:
return nums
for i in range(n-k,n):
nums1[cnt]=nums[i]
cnt+=1
for i in range(0,n-k):
nums1[cnt]=nums[i]
cnt+=1
nums[:]=nums1
return nums
更简洁的思路:
三次反转(最优解 - O(1) 空间复杂度)
这是一个非常巧妙的方法,不需要任何额外的数组。
思路
- 反转整个数组 。例如
[1,2,3,4,5,6,7]
变为[7,6,5,4,3,2,1]
。 - 反转前 k 个元素 。
[7,6,5]
变为[5,6,7]
,数组变为[5,6,7,4,3,2,1]
。 - 反转后 n-k 个元素 。
[4,3,2,1]
变为[1,2,3,4]
,数组变为[5,6,7,1,2,3,4]
。
Python 代码示例
python
class Solution(object):
def rotate(self, nums, k):
n = len(nums)
k = k % n
# 定义一个辅助函数来反转数组的特定部分
def reverse(start, end):
while start < end:
nums[start], nums[end] = nums[end], nums[start]
start += 1
end -= 1
# 步骤 1: 反转整个数组
reverse(0, n - 1)
# 步骤 2: 反转前 k 个元素
reverse(0, k - 1)
# 步骤 3: 反转后 n-k 个元素
reverse(k, n - 1)
这个方法是这道题目的最优解,因为它只在原数组上操作,空间复杂度是 O(1)O(1)O(1)。
数组大小硬编码和返回值
Python和C++不一样,这道题应该根据题目输入来指定数组大小
nums1=[None]*100000
这种写法创建了一个固定大小的巨大数组。如果输入的 nums
长度只有 7, nums1
会是 [5, 6, 7, 1, 2, 3, None, None, ...]
,这显然是不对的。应该创建一个和 nums
等长的临时数组。
nums=nums1一般不能这么对数组赋值
nums = nums1
只是让两个名字指向同一个列表对象 ;不会把内容"拷贝/写回"到原列表里。
更靠谱的几种写法:
- 原地覆盖(推荐用于题目要求 in-place)
python
nums[:] = nums1 # 把 nums1 的内容写进 nums 本体
- 拷贝出一个新列表(不原地)
python
b = nums1[:] # 浅拷贝
c = list(nums1) # 浅拷贝
# 若是嵌套列表需要深拷贝:
# import copy; d = copy.deepcopy(nums1)
- 为什么
nums = nums1
不行?(两个层面)
- 别名问题 :之后改
nums.append(9)
,nums1
也会跟着变,因为它们是同一个对象。 - 函数参数绑定 :在函数内写
nums = nums1
只是把局部变量nums
重新绑定;调用者传进来的那个列表对象没被改 。要么修改nums[:]
,要么对nums
做.append/.pop/...
这类原地操作。
示例:
python
def f(nums):
other = [7,8,9]
nums = other # 只是改了局部绑定,外面的 nums 不变
x = [1,2,3]
f(x)
print(x) # 仍是 [1,2,3]
def g(nums):
other = [7,8,9]
nums[:] = other # 原地覆盖
g(x)
print(x) # 变成 [7,8,9]
正确做法:用切片赋值 nums[:] = nums1