Вот попытка рекурсивного подхода. Это похоже на уплощение массива или нахождение соответствующих круглых скобок, с той сложностью, что мы можем иметь до трех элементов до t ie вместе на удаленных секциях.
Очень легко проверенный JavaScript код (контрпримеры / ошибки приветствуются ):
// Returns [count, leftmostIndex]
function f(A, i=0, same=1){
// Base case, end of list
if (i > A.length - 1)
return [0, A.length];
// We can remove this block
if (A[i] == A[i+1] && same == 2){
let [count, j] = f(A, i + 2, 1);
return [count + 1, j];
}
// Same but the count is less than
// three, keep accumulating
if (A[i] == A[i+1])
return f(A, i + 1, same + 1);
// Next element is different,
// see if the next section has
// collapsed blocks
let [count, j] = f(A, i + 1, 1);
// There is no available element
// to try and accumulate
if (j > A.length - 1)
return [count, i];
// The next available element
// is the same
if (A[i] == A[j]){
// We've reached a count of three,
// remove this block
if (same == 2){
return [count + 1, j + 1];
// Haven't reached a count of
// three, try one more section
} else {
let [count2, j2] = f(A, j + 1, 1);
if (A[i] == A[j2])
return [1 + count + count2, j2 + 1];
else
return [count + count2, i];
}
// The next available element is
// different
} else {
return [count, i];
}
}
var As = [
[4,4,7,7,6,6,6,7,4],
[5,7,7,7,8,4,4,5,5,6,6,6,6,6,6,5,4]
];
for (let A of As){
console.log(JSON.stringify(A));
console.log(JSON.stringify(A.map((_, i) => i)));
console.log(JSON.stringify(f(A)));
}