这个问题来自this answer的评论中的讨论。
首先,让我们说定义乱序是很困难的。以Pavel Shved为例,在列表[1,5,10,2,3,4,5,6,7,8,9,10,11]中我们可以“清楚地”看到5和10(指数1) 2)发生故障。但是,一种简单地检查某种排序列表不变量的简单算法就不会指出这些算法。
检查a[i-1]<=a[i] for all 0<i<=N
会产生索引3处的元素(即2);
检查a[j]<=a[i] for all 0<=i<=N and 0<=j<=i
会产生索引3到12中的所有元素;
我的问题是:你能想到一个算法来解决这个产生“正确答案”的问题(即指数1和2)吗?如果是这样,它会在什么时间和内存复杂度下运行?
答案 0 :(得分:10)
对此最好的方法可能是首先找到longest increasing subsequence,然后将所有不属于该序列的元素视为乱序。链接页面上提供的算法在O(n log n)
时间运行并使用O(n)
空间(除了列表本身的空间)。
这种方法肯定会为您的示例案例提供正确的答案,因为最长的增加子序列将是1到11序列,不包括额外的5和10。
答案 1 :(得分:1)
算法应该如何知道您认为哪些元素无序?
如果规则是“list [i + 1]应该始终是list [i] + 1”,那么它很容易,当然,只记住1之后,下一个元素应该是2,选择那些之间等等。但是,您需要一个精确的算法规则来确定哪些元素被视为“无序”。
答案 2 :(得分:0)
正如戴维所说,longest increasing subsequence可能是你能做的最好的。
这是我的头脑,所以它可能(读取可能不是:P)正确: 此问题的明显下限是O(n),因为您至少必须读取每个数字一次。但是假设有一个算法在O(n)时间内运行。然后你可以简单地按线性时间顺序插入乱序元素,但最好的比较排序算法的下限为O(nLogn),所以这是一个矛盾。 (否则,有非比较排序方法,如桶或基数排序,使用大量内存或利用正在排序的数字的大小...)