I think this should work for you. It finds the longest subsequence and then clears up the other elements. The implementation is in c#
public static void Main() {
int[][] dataList = {
new []{20,30,21,22,23,24,25},
new []{30,31,21,22,23,24,25},
new []{30,21,22,23,24,25,26},
new []{20,21,22,23,18,25,26},
new []{20,15,21,22,23,24,25}
};
foreach (var data in dataList)
DetectAndRemoveUnsorted(data);
}
/// <summary>
/// Assumes ascending data. You can adapt it for descending data too
/// </summary>
static void DetectAndRemoveUnsorted(IList<int> data) {
// first pass: Find the outliers; rather find the correct sequence
int startOfLongestSeq = 0, lenOfLongestSeq = 0;
int startOfCurrSeq = 0, lenOfCurrSeq = 0;
for (int i = 0; i < data.Count - 1; ++i) {
if (data[i] > data[i + 1]) { // we are breaking the ascending order, so this is another sequence
lenOfCurrSeq = i - startOfCurrSeq + 1;
if (lenOfCurrSeq > lenOfLongestSeq) {
lenOfLongestSeq = lenOfCurrSeq;
startOfLongestSeq = startOfCurrSeq;
}
startOfCurrSeq = i + 1;
}
}
lenOfCurrSeq = data.Count - startOfCurrSeq;
if (lenOfCurrSeq > lenOfLongestSeq) {
lenOfLongestSeq = lenOfCurrSeq;
startOfLongestSeq = startOfCurrSeq;
}
// second pass: cleanup outliers
// now we know which sequence is the largest
// we should get rid of the other sequences
for (int i = startOfLongestSeq - 1; i >= 0; --i)
data[i] = -1; // Mark them as invalid. if you want, you can delete them as well
for (int i = data.Count - 1; i >= startOfLongestSeq + lenOfLongestSeq; --i)
data[i] = -1; // Mark them as invalid. if you want, you can delete them as well
}