Description
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.
Example:
Input:
s = "++++"
Output: true
Explanation: The starting player can guarantee a win by flipping the middle"++"
to become"+--+"
.
Follow up:
Derive your algorithm's runtime complexity.
Solution
Backtracking, O(n!), S(n)
时间复杂度有人说是O(n!!)?待研究。
The idea is try to replace every "++" in the current string s to "--" and see if the opponent can win or not, if the opponent cannot win, great, we win!
class Solution {
public boolean canWin(String s) {
if (s == null || s.length() < 2) {
return false;
}
return canWin(s.toCharArray());
}
private boolean canWin(char[] arr) {
// try to find a solution making nextCanNotWin
boolean nextCanWin = true;
for (int i = 0; i < arr.length - 1 && nextCanWin; ++i) {
if (arr[i] == '+' && arr[i + 1] == '+') {
arr[i] = '-';
arr[i + 1] = '-';
nextCanWin = canWin(arr);
arr[i] = '+'; // don't forget to revert, even if nextCanNotWin!
arr[i + 1] = '+';
}
}
return !nextCanWin;
}
}
Backtracking with memo, O(?), S(?)
class Solution {
public boolean canWin(String s) {
if (s == null || s.length() < 2) {
return false;
}
return canWin(s.toCharArray(), new HashMap<>());
}
private boolean canWin(char[] arr, Map<String, Boolean> memo) {
if (memo.containsKey(new String(arr))) {
return memo.get(new String(arr));
}
// try to find a solution making nextCanNotWin
boolean nextCanWin = true;
for (int i = 0; i < arr.length - 1 && nextCanWin; ++i) {
if (arr[i] == '+' && arr[i + 1] == '+') {
arr[i] = '-';
arr[i + 1] = '-';
nextCanWin = canWin(arr, memo);
arr[i] = '+'; // don't forget to revert, even if nextCanNotWin!
arr[i + 1] = '+';
}
}
boolean canWin = !nextCanWin;
memo.put(new String(arr), canWin);
return canWin;
}
}
网友评论