我应该对数字列表进行排序,但是我很懒。很难弄清楚如何交换所有数字,直到所有数字都按升序排列,所以我想出了自己的算法来保证新列表的排序。运作方式如下:
对于大小为N的列表,我们需要N-1次迭代。在每次迭代中
检查第N个数字是否小于第N + 1个数字。如果是,则这两个数字已经排序,因此我们可以跳过此迭代。
如果不是,那么您需要连续递减前N个数字,直到这两个数字顺序正确为止。
让我们举一个具体的例子。假设输入是
10 5 7 6 1
在第一个迭代中,我们将比较10和5。10大于5,因此我们将其递减直到更小:
4 5 7 6 1
现在我们比较5和7。5小于7,因此在此迭代中无需执行任何操作。因此,我们转到下一个并比较7和6。7大于6,因此我们递减前三个数字,直到小于6,我们得到:
2 3 5 6 1
现在我们比较6和1。同样,6大于1,因此我们将前四个数字减1,直到小于1,我们得到:
-4 -3 -1 0 1
我们完成了!现在,我们的列表已按完美排序。而且,为了使事情变得更好,我们只需要遍历列表N-1次,因此该算法以O(N-1)时间对列表进行排序,我敢肯定,这是最快的算法。²
今天的挑战是实现这种惰性排序。您的程序或函数将获得任意喜欢的标准格式的整数数组,并且您必须执行此惰性排序并返回新的“已排序”列表。数组永远不会为空或包含非整数。
这里有些例子:
Input: 10 5 7 6 1
Output: -4 -3 -1 0 1
Input: 3 2 1
Output: -1 0 1
Input: 1 2 3
Output: 1 2 3
Input: 19
Output: 19
Input: 1 1 1 1 1 1 1 1 1
Output: -7 -6 -5 -4 -3 -2 -1 0 1
Input: 5 7 11 6 16 2 9 16 6 16
Output: -27 -25 -21 -20 -10 -9 -2 5 6 16
Input: -8 17 9 7
Output: -20 5 6 7
和往常一样,这是代码高尔夫,因此,请写出最短的程序!
¹ 这并不意味着听起来像什么,但这在技术上是真实的
² 我在开玩笑,请不要恨我
<sarcasm>
实际上,这种排序算法仍然会O(N^2)
耗时,因为您必须遍历列表中所有以前访问的项目才能减少它们。我建议倒排整个列表,并在必要时每步只减少一个数字。这将为您带来真正的O(N)
复杂性!</sarcasm>
O(n^2)
就内存访问而言,@ ValueInk 是不是O(n)
用于比较?
O(N^2)
。