有人可以解释为什么在next permutation algorithm中,我们将O(n)视为最坏情况而O(1)是最佳情况?一个例子的解释将被赞赏......
算法是:
找到最大的索引k,使得a [k]< a [k + 1]。如果不存在这样的索引,则排列是最后的排列。
找到大于k的最大索引l,使得a [k] <一个[1]。
将[k]的值与[l]的值交换。
将序列从[k + 1]反转到包括最后一个元素a [n]。
我是学习算法的新手。所以,对我来说,想象一下这个算法中最糟糕和最好的情况是有点困难。 感谢。
答案 0 :(得分:0)
它在O(n)中的原因是你必须找到两个特定字符。一般来说,如果算法依赖于你从n个列表中找到一个特定的东西,算法将在O(n)中,但在最好的情况下将是恒定的时间。为了帮助可视化它,让我们在几个字符串上跟踪算法。
考虑给出字符串
,考虑找到下一个排列a = 6 7 5 4 3 2 1
我们必须首先找到最右边的字符,然后才能找到它后面的字符。为此,我们可以向后搜索字符串:
6 7 5 4 3 2 1
6 7 5 4 3 2 1
6 7 5 4 3 2 1
6 7 5 4 3 2 1
6 7 5 4 3 2 1
6 7 5 4 3 2 1发现它!
进行了6次比较。让我们调用左索引k,给我们k = 0。现在你必须找到大于k的最右边的字符。我们可以通过向后查看列表再次执行此操作。
6 7 5 4 3 2 1
6 7 5 4 3 2 1
6 7 5 4 3 2 1
6 7 5 4 3 2 1
6 7 5 4 3 2 1
6 7 5 4 3 2 1发现它!
进行了6次比较。让我们称之为索引l,给出k = 0和l = 1。现在,交换这两个值。
6 7 5 4 3 2 1 - &gt; 7 6 5 4 3 2 1
现在将序列从k + 1反转到列表末尾。我不打算写出来,因为我不认为理解算法特别重要,但不是这不是一个恒定的时间操作。如果使用数组,则反转元素将是线性的。这不会改变效率等级。
7 6 5 4 3 2 1 - &gt; 7 1 2 3 4 5 6
你有下一个排列!我认为很难看出这是最糟糕的情况。这需要6 + 6 = 12次比较,等于2 *(长度(a)-1)。如果我们扩展这个,我们得到2 *长度(a) - 2.两个都可以被删除,因为我们不关心big-O中的常数加法或乘法,我们留下长度(a),将算法放入上)。
<小时/>
现在让我们看一下(更短的)最佳案例。
a = 1 2 3 4 5 6 7
找到k
1 2 3 4 5 6 7 发现它!
找到l
1 2 3 4 5 6 7 发现它!
交换k和l
1 2 3 4 5 6 7 - &gt; 1 2 3 4 5 7 6
并在k之后反转所有字符。
1 2 3 4 5 7 6 - &gt; 1 2 3 4 5 7 6
在这种情况下,我们只需要进行单一比较来找到k和单个比较来找到l。在k之后反转元素也是一个恒定时间操作,因为只有一个元素可以反转。无论字符串是7个字符长还是100,000,000个字符长,都是如此。找到这种排列与字符串的长度无关,最好的情况是O(1)。