Это решение следующей проблемы.
По сути, у вас есть строка символов «-» и «+»:
++-++++
Вы переворачиваете два последовательных «+» в «-», затем ваш друг делает то же самое, затем возвращается к вам и так далее. Как только кто-то не может сделать ход, он проигрывает.
Итак, в приведенной выше игре, если вы ходите первым, вы выигрываете, переворачивая либо два последних «+», либо два средних «+» (подумайте об этом).
Вот алгоритм, который решает, выигрывает ли игрок, идущий первым:
public boolean canWin(String s) {
for (int i = 0; i < s.length() - 1; ++i)
if (s.charAt(i) == '+' && s.charAt(i + 1) == '+' &&
!canWin(s.substring(0, i) + "--" + s.substring(i + 2)))
return true;
return false;
}
По сути, алгоритм рекурсивно говорит: «Игрок, идущий первым, выигрывает, если он может уменьшить доску до состояния, в котором игрок, идущий первым, проигрывает».
Вот мои мысли о временной сложности:
Пусть N будет количеством символов на доске.
В худшем случае ходов N-1 (если все «+»). Каждый ход уменьшает доску (в худшем случае) всего на 2 хода.
Но потом я застреваю. Я знаю, что это хуже, чем N*(N-2)*(N-4)*...*1, но не могу сформулировать.