最后更新
三刷。
某一个状态下不能赢,说明上一个状态赢了,上上个状态输了,上上上个状态赢了。。但是越往上状态越是不一定的。。
所谓的状态其实就是input的情况。 这个题更像是DFS+状态记录,只不过提前结束的情况比较早。
public class Solution {
Map<String, Boolean> map = new HashMap<>();
public boolean canWin(String s) {
if (s.length() < 2) return false;
boolean win = false;
char[] strs = s.toCharArray();
for (int i = 1; i < strs.length; i++) {
if (!(strs[i] == '+' && strs[i-1] == '+')) continue;
strs[i] = '-';
strs[i-1] = '-';
String tempS = new String(strs);
win = !canWin(tempS);
if (win) {
map.put(tempS, win);
return true;
}
strs[i] = '+';
strs[i-1] = '+';
}
return win;
}
}
一刷。
这个题上来没找对思路,以为有什么数学思想在里面,列举了2-9的情况,也没研究个明白。
然后看TAG是BACK-TRACK。。似乎只能是这个样。
无非是看当前走这一步,然后下一步该你了,你下一步能不能赢,不能赢就是我赢了。。
time complexity应该是指数级别的。。
用DP ARRAY记录可以省去重复计算。。
public class Solution
{
Map<String,Boolean> map = new HashMap<String,Boolean>();
public boolean canWin(String s)
{
if(s.length() < 2) return false;
if(map.containsKey(s)) return map.get(s);
char[] str = s.toCharArray();
for(int i = 0; i < str.length-1;i++)
{
if(str[i] == '+' && str[i+1] == '+')
{
str[i] = '-';
str[i+1] = '-';
String tempStr = new String(str);
if(!canWin(tempStr))
{
map.put(tempStr,false);
return true;
}
str[i] = '+';
str[i+1] = '+';
}
}
map.put(s,false);
return false;
}
}
二刷
赢的标致是,走完这步对方无路可走。。。
如果对方下一步无路可走,就证明赢了;如果有路,这步就不这么走,试试别的走法。
top-down里使用记忆的一种典型。唯一的不同是这个题可以提前结束。
public class Solution {
Map<String, Boolean> map = new HashMap<>();
public boolean canWin(String s) {
if (s.length() < 2) return false;
if (map.containsKey(s)) return map.get(s);
char[] chArray = s.toCharArray();
boolean res = false;
for (int i = 0; i < chArray.length - 1; i++) {
if (chArray[i] == '+' && chArray[i+1] == '+') {
chArray[i] = '-';
chArray[i+1] = '-';
String nextS = new String(chArray);
boolean nextPlayer = canWin(nextS);
if (!nextPlayer) {
res = true;
break;
}
chArray[i] = '+';
chArray[i+1] = '+';
}
}
map.put(s, res);
return res;
}
}
这里的复杂度比较麻烦。。
上面是用了记忆搜索的办法。
比如有N个 +
算了半天算乱了。。直接给别人的答案吧。。
(https://discuss.leetcode.com/topic/27282/theory-matters-from-backtracking-128ms-to-dp-0ms)
T(N) = (N-2) * T(N-2) = (N-2) * (N-4) * T(N-4) ... = (N-2) * (N-4) * (N-6) * ... ~ O(N!!)
还有O(n^2)的做法,看了两行就不想看了。