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 };

 

posted @ 2020-02-22 23:33  NeoZy  阅读(398)  评论(0编辑  收藏  举报