leetcode-10:还原排列的最少操作步数

Posted 坚持不懈的大白

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了leetcode-10:还原排列的最少操作步数相关的知识,希望对你有一定的参考价值。

原题描述如下:

给你一个偶数 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 回到排列初始值,至少需要执行多少步操作?返回最小的 非零 操作步数。
题目链接为:还原排列的最少操作步数

1. 暴力算法

最让人容易想到的肯定是暴力算法呀!不过这样时间复杂度和空间复杂度都很高,虽然可以成功提交,但是在leetcode相比较其他用户而言,差太多了。

class Solution(object):
   def reinitializePermutation(self, n):
       """
       :type n: int
       :rtype: int
       """
       perm = [i for i in range(n)]
       perm1 = perm
       res = 0
       arr = [0 for i in range(n)]
       while arr != perm:
           arr = [0 for i in range(n)]
           for i in range(n):
               if i%2 == 0:
                   arr[i] = perm1[i//2]
               else:
                   arr[i] = perm1[n//2+(i-1)//2]
           res += 1
           perm1 = arr
       return res
   # 暴力算法

2. 利用数学知识找规律

下面就演示一下这个排列perm中数据的变化:
n = 6 时,res = 4

index     0  1  2  3  4  5
data      0  1  2  3  4  5
1         0  3  1  4  2  5
2         0  4  3  2  1  5
3         0  2  4  1  3  5
4         0  1  2  3  4  5

n = 8 时,res = 3

index     0  1  2  3  4  5  6  7
data      0  1  2  3  4  5  6  7
1         0  4  1  5  2  6  3  7
2         0  2  4  6  1  3  5  7
3         0  1  2  3  4  5  6  7

小编发现如果根据数据1的下标索引index的变化,可以发现如下规律如下:

  • 如果index*2小于n,那么index = index*2;
  • 否则index = (index-n/2)*2+1

其实这个是可以根据题意推出来的:
因为数据1的下标索引初始值是1,那么经过1次操作之后,它的下标索引值变为2,再经过1次操作之后,它的下标索引变为4,以此类推;当数据1的下标索引乘以2已经大于n了,显然已经不能用上述计算方式,此时计算方式应为:下标索引 = (上次的下标索引-n/2)*2+1(根据arr[i] = perm[n / 2 + (i - 1) / 2]倒推即可),读者自己尝试几次数据变化就会发现如上规律。

如果经过上述变化,数据1的下标索引正好等于n/2,此时的变化次数+1即是这个算法题目结果(描述的可能不是很清楚哈!)。
参考代码为:

class Solution(object):
    def reinitializePermutation(self, n):
        """
        :type n: int
        :rtype: int
        """
        index = 1
        res = 1
        while index != n//2:
            if index*2 < n:
                index = index*2
            else:
                index = (index - n//2)*2+1
            res +=1

        return res

运行结果:

以上是关于leetcode-10:还原排列的最少操作步数的主要内容,如果未能解决你的问题,请参考以下文章

[1806] LeetCode 刷题笔记: 还原排列的最少操作步数 [M]

联合省选 选做

NYOJ-最少步数

cdoj1588 潘爷泡妹

最少步数

例8.3最少步数