Flip Game II

update Sep 10, 2017 17:00

LeetCodearrow-up-right

You are playing the following Flip Game with your friend: Given a string that contains only these two characters: + and -, you and your friend take turns to flip two consecutive "++" into "--". The game ends when a person can no longer make a move and therefore the other person will be the winner.

Write a function to determine if the starting player can guarantee a win.

For example, given s = "++++", return true. The starting player can guarantee a win by flipping the middle "++" to become "+--+".

Follow up: Derive your algorithm's runtime complexity.

Basic Idea:

这道题目所描述的是一个典型有最优选择策略的零和游戏,其特点是当 canWin==True 的时候,我们必胜,当 canWin==False 的时候,不是不知道我们能否获胜,而是当对方也采取最优策略的时候,我们必败。

由上面的分析,我们就可以得到一种思路:

  • 对一个 input string s,我们可以有 k 种 flip 一步的方案;

  • 对每一个方案,会有一个 next string,这个next就是丢给下家的;

  • 我们只要判断 if (! canWin(next)), 就说明下家一定赢不了,也说明我们必胜;

  • 此时我们就选择这条路,因为如此必胜,所以可以直接返回 True;

接下来,我们注意到其中可能会有重复,而且是否 canWin 是和每个input string s 一一对应的,我们可以由此用 Memoized Dynamic Programming 的思路进行优化,维持一个 Map<String, Boolean>, 为每个遇见的 s 记录其是否 canWin;

Time Complexity: 我们实际上在穷举所有可能的情况,对于 input like : “+++++++++++”,我们有大约 P(n, n) 种不同的操作方法,是 O(n!) 的,但是经过优化之后,显然已经有了很大的进步, 最终应该是 O(2^n)。

Java Code: