Arrays 删除近似排序数组中的未排序/异常元素

Arrays 删除近似排序数组中的未排序/异常元素,arrays,algorithm,sorting,outliers,trendline,Arrays,Algorithm,Sorting,Outliers,Trendline,给定一个类似于[15,14,12,3,10,4,2,1]的数组。如何确定哪些元素出现了故障并将其删除(本例中的数字3)。我不想对列表进行排序,但要检测异常值并删除它们 另一个例子: [13,12,4,9,8,6,7,3,2] 我希望能够删除#4和#7,以便最终得到: [13,12,9,8,6,3,2] 在这种情况下,还会出现一个问题: [15,13,12,7,10,5,4,3] 您可以删除7或10以对该数组进行排序 一般来说,我试图解决的问题是,给定一个数字读数列表(有些读数可能会偏离一点)。我

给定一个类似于
[15,14,12,3,10,4,2,1]
的数组。如何确定哪些元素出现了故障并将其删除(本例中的数字3)。我不想对列表进行排序,但要检测异常值并删除它们

另一个例子:

[13,12,4,9,8,6,7,3,2]

我希望能够删除#4和#7,以便最终得到:

[13,12,9,8,6,3,2]

在这种情况下,还会出现一个问题:

[15,13,12,7,10,5,4,3]

您可以删除7或10以对该数组进行排序


一般来说,我试图解决的问题是,给定一个数字读数列表(有些读数可能会偏离一点)。我希望数组只包含遵循一般趋势线的值,并删除任何异常值。我只是想知道是否有一种简单的方法可以做到这一点。

higuaro描述的一种简单算法可以帮助您生成正确的序列:

对于索引
i
处的每个元素,如果
a[i]
,我们可以简单地删除该元素
a[i]

for(int i = 0; i < size; i++)
    while(a[i] < a[i + 1]){
       remove a[i];
       i--;
    }
for(int i=0;i
然而,这种方法不能保证移除的元素数量是最小的。例如,对于这个序列[10,9,8,100,1,0],移除100将是最佳的,而不是移除8,然后移除9然后移除10


为了找到要删除的元素的最小数量,我们注意到我们需要找到最长的递减子序列,这类似于经典的解决方案,我将把您的问题归结为最长的递增(递减)子序列问题

由于您的序列几乎已排序,因此您肯定会收到令人满意的结果(即整齐地跟随趋势线)

有许多解决办法;其中一个是斯维特林·纳科夫和维塞林·科列夫在《自由书》中描述的;问题在第257页练习6中给出;解决方案见第260页

摘自该书:

编写一个程序,在数组arr[n]中查找递增元素的最大序列。元素不必连续放置。例如:{9,6,2,7,4,7,6,5,8,4}->{2,4,6,8}

解决方案:

我们可以用两个嵌套循环和一个以上的数组len[0…n-1]来解决这个问题。在数组len[i]中,我们可以保持最长的连续递增序列的长度,该序列从数组中的某个位置开始(确切位置并不重要),以元素arr[i]结束。因此len[0]=1,len[x]是最大和max(1+len[prev]),其中prev 所述算法查找所有最大升序序列的长度,这些序列在每个元素处结束。这些值中最大的一个是最长递增序列的长度。如果我们需要找到组成最长序列的元素本身,我们可以从元素开始,序列在那里结束(在索引x处),我们可以打印它,我们可以搜索前一个元素(prev)。根据prev
您能否删除满足以下条件的第一个元素:
a[i]
?(O(n))您想删除最少数量的元素,还是任意数量都可以?我喜欢@higuaro的想法,但我如何处理多个异常元素?@PhamTrung minimum,如果可能的话,我想就是这样!让我试试。我们为什么不删除[i+1]呢?这将删除100,这将是最佳的。所以代码应该是`
for(inti=0;i
@NikhilJagdale我们可以很容易地找到一个例子,它会使您的解决方案输出不正确的结果,例如,这个序列
[100,99,5,98,97,96]
->正确的解决方案是
[100,99,98,97,96]
,您的输出是
[100,99,5]