294. 翻转游戏 II
题目:
链接:https://leetcode-cn.com/problems/flip-game-ii/
你和朋友玩一个叫做「翻转游戏」的游戏,游戏规则:给定一个只有 + 和 - 的字符串。你和朋友轮流将 连续 的两个 "++" 反转成 "--"。 当一方无法进行有效的翻转时便意味着游戏结束,则另一方获胜。
请你写出一个函数来判定起始玩家是否存在必胜的方案。
示例:
输入: s = "++++"
输出: true
解析: 起始玩家可将中间的 "++" 翻转变为 "+--+" 从而得胜。
延伸:
请推导你算法的时间复杂度。
还是太菜了,中等题目都做不出来。
方法:就是递归回溯,复杂度n^n(不确定)
传值的:
1 class Solution { 2 public: 3 bool canWin(string s) { 4 for(int i = 0; i < s.size(); ++i){ 5 if(i + 1 < s.size() && s[i] == '+' && s[i + 1] == '+'){//找任何一种方法让对方赢不了,我就赢了 6 string tmp = s; 7 tmp[i] = '-', tmp[i + 1] = '-'; 8 if(!canWin(tmp)){ 9 return true; 10 } 11 } 12 } 13 return false; 14 } 15 };
传引用的:
1 class Solution { 2 public: 3 bool canWin(string& s) { 4 if (!s.length()) 5 return false; 6 int ptr = 0; 7 while (ptr < s.length() - 1) { 8 if (s[ptr] == s[ptr + 1] && s[ptr] == '+') { 9 s[ptr] = s[ptr + 1] = '-'; 10 if (!canWin(s)) { 11 s[ptr] = s[ptr + 1] = '+'; 12 return true; 13 } 14 s[ptr] = s[ptr + 1] = '+'; 15 } 16 ptr++; 17 } 18 return false; 19 } 20 };
记忆化搜索(用map保存找过的情况):
1 class Solution { 2 public: 3 unordered_map<string, bool> memo; 4 bool canWin(string s) { 5 if (memo.count(s)) return memo[s]; 6 for (int i = 1; i < s.size(); ++i) { 7 if (s[i] == '+' && s[i - 1] == '+') { 8 string t = s; 9 t[i] = t[i - 1] = '-'; 10 if (!canWin(t)) { 11 memo[s] = true; 12 return true; 13 } 14 } 15 } 16 memo[s] = false; 17 return memo[s]; 18 } 19 };
进击的小🐴农