题目
给你一个偶数 n ,已知存在一个长度为 n 的排列 perm ,其中 perm[i] == i(下标 从 0 开始 计数)。一步操作中,你将创建一个新数组 arr ,对于每个 i :
如果 i % 2 == 0 ,那么 arr[i] = perm[i / 2]
如果 i % 2 == 1 ,那么 arr[i] = perm[n / 2 + (i - 1) / 2]
然后将 arr 赋值给 perm 。
要想使 perm 回到排列初始值,至少需要执行多少步操作?返回最小的 非零 操作步数。
示例
输入:n = 4
输出:2
解释:最初,perm = [0,1,2,3]第 1 步操作后,perm = [0,2,1,3]第 2 步操作后,perm = [0,1,2,3]所以,仅需执行 2 步操作
方法1 直接求解
题目非常好理解,对于perm中的每个索引i,按如下规则进行变换:
i为偶数,arr[i]=perm[i // 2]
i为奇数,arr[i]=perm[n // 2 + (i - 1) // 2]
然后将arr赋给perm即可,题目里的最小执行步骤这个有些迷惑性。到这里直接可以写代码了:
class Solution:
def reinitializePermutation(self, n: int) -> int:
perm = list(range(n))
#用于对比
target = perm.copy()
step = 0
while True:
step += 1
#不能直接在perm上修改,因为perm的该动会导致结果出错,当然可以使用推导式的方法写
arr=list(range(n))
for i in range(n):
if i%2:
arr[i]=perm[n // 2 + (i - 1) // 2]
else:
arr[i]=perm[i // 2]
#perm = [perm[n // 2 + (i - 1) // 2] if i % 2 else perm[i // 2] for i in range(n)]
perm=arr
if perm == target:
return step
计算复杂性
时间复杂度,其中 n表示给定的元素。根据方法二的推论可以知道最多需要经过n次变换即可回到初始状态,每次变换需要的时间复杂度为 $O(n)$,因此总的时间复杂度为$O(n^2)$
空间复杂度,其中n表示给定的元素。我们需要存储每次变换中的过程变量,需要的空间为 $O(n)$。