我正在解决以下问题:
我必须通过删除最小数量的元素将给定的整数数组转换为已排序的整数。
例如:[3,5,2,10,11]将通过删除'2'进行排序:[3,5,10,11]。 或者[3,6,2,4,5,7,7]将通过删除'3','6'排序:[2,4,5,7,7]或删除'6','2' :[3,4,5,7,7](两种方式我都删除了2个元素,这就是为什么它们都是正确的。)
我的想法是为每个元素保留一个计数器,以查看它与其他元素有多少冲突。 我的意思是冲突:在第一个例子中,数字'3'和'5'各有1个冲突(数字'2'),数字'2'有2个冲突(数字'3'和'5') 。 因此,在计算冲突数组后,我从原始数组中删除了具有最大冲突数的元素,并且我重复其余数组,直到所有元素都有0个冲突。
虽然这不是一种有效的方法(在某些情况下,我认为它也可能产生错误的结果),所以我想知道是否有人能想到更好的解决方案。
答案 0 :(得分:6)
我认为这只是 longest increasing subsequence problem的一个巧妙伪装的版本。如果你删除了具有排序序列的最小元素数,那么你剩下的就是最长的增加原始数组的子序列。因此,您可以执行以下操作:
希望这有帮助!
答案 1 :(得分:2)
您可以根据数组中的元素构建DAG:
对于任何元素对(m,n),其中(m 优化:您可以为已排序的子阵列构建简单的链。例如,如果a [m]< = a [m + 1]< = a [m + 2]< = a [m + 3]> a [m + 4],则可以跳过添加边缘顶点m的(m,m + 2)和(m,m + 3)。
现在的目标是找到longest path in the graph,它具有有向无环图的线性时间解。
在上述维基百科页面和here中描述了一种算法。
答案 2 :(得分:0)
我会用递归编程来做。这是我的伪代码:
/**
* sortedArray : an array already sorted.
* leftToSort : an unsorted array that need to be sorted/merged with sortedArray.
* first call to this function must be sortArrayByRemoval([], arrayToSort);
**/
public Integer[] sortArrayByRemoval(Integer[] sortedArray, Integer[] leftToSort){
if(leftToSort.size==0){
return sortedArray; //end of recursion
}
Integer candidate = leftToSort[0];
if(candidate>=sortedArray[last]){ //append candidate to the sorted array
return sortArrayByRemoval(sortedArray.append(candidate) , leftToSort.removeFirst());
}else{
//either we skip it
Integer[] result1 = sortArrayByRemoval(sortedArray,leftToSort.removeFirst());
//either we do back tracking
Integer[] result2 = sortArrayByRemoval(sortedArray.removeLast(),leftToSort);
//and finally we return the best choice (i.e. the longest array)
return biggestArray(result1, result2);
}
}
也许不是最有效的,但我认为它会给你正确答案。
答案 3 :(得分:0)
如果您没有坚持从原始数组中删除字样的想法,那么您想要的是原始数字序列中增长最快的子序列。这是一个众所周知的经典问题,你可以在文献或教科书中找到很多例子。
(如果您坚持删除,那么......找到LCS并删除LCS中没有的所有内容。)