题目:
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.
递归或者 Game Theory。
C++版:
class Solution {
public:
bool canWin(string s) {
int cur = 0, maxL = 0;
vector<int> subGames;
for(int i = 0; i < s.length(); i++) {
if(s[i] == '+') {
cur++;
if(cur >= 2 && (i == s.length() - 1 || s[i + 1] == '-')) {
subGames.push_back(cur);
maxL = max(maxL, cur);
cur = 0;
}
} else
cur = 0;
}
vector<int> eachGame(maxL + 1, 0);
for(int i = 2; i <= maxL; i++) {
unordered_set<int> nums;
for(int j = 0; j < i / 2; j++) {
int k = i - j - 2;
nums.insert(eachGame[j] ^ eachGame[k]);
}
eachGame[i] = firstMissingNumber(nums);
}
int result = 0;
for(auto i : subGames)
result ^= eachGame[i];
return result != 0;
}
int firstMissingNumber(unordered_set<int>& s) {
int l = s.size();
for(int i = 0; i < l; i++)
if(s.count(i) == 0)
return i;
return l;
}
};
Python版:
class Solution(object):
def canWin(self, s):
"""
:type s: str
:rtype: bool
"""
if len(s) < 2:
return False
for i in range(len(s) - 1):
if s[i] == '+' and s[i+1] == '+' and not self.canWin(s[:i] + '-' + s[i+2:]):
return True
return False