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.

这道题是之前那道 Flip Game 的拓展,让我们判断先手的玩家是否能赢,可以穷举所有的情况,用回溯法来解题,思路跟上面那题类似,也是从第二个字母开始遍历整个字符串,如果当前字母和之前那个字母都是+,那么递归调用将这两个位置变为--的字符串,如果返回 false,说明当前玩家可以赢,结束循环返回 false。这里同时贴上热心网友 iffalse 的解释,这道题不是问 “1p是否会怎么选都会赢”,而是 “如果1p每次都选特别的两个+,最终他会不会赢”。所以 canWin 这个函数的意思是 “在当前这种状态下,至少有一种选法,能够让他赢”。而 (!canWin) 的意思就变成了 “在当前这种状态下,无论怎么选,都不能赢”。所以 1p 要看的是,是否存在这样一种情况,无论 2p 怎么选,都不会赢。所以只要有一个 (!canWin),1p 就可以确定他会赢。这道题从博弈论的角度会更好理解。每个 player 都想让自己赢,所以每轮他们不会随机选+。每一轮的 player 会选能够让对手输的+。如果无论如何都选不到让对手输的+,那么只能是当前的 player 输了,参见代码如下:

解法一:

class Solution {
public:
bool canWin(string s) {
for (int i = ; i < s.size(); ++i) {
if (s[i] == '+' && s[i - ] == '+' && !canWin(s.substr(, i - ) + "--" + s.substr(i + ))) {
return true;
}
}
return false;
}
};

第二种解法和第一种解法一样,只是用 find 函数来查找 ++ 的位置,然后把位置赋值给i,然后还是递归调用 canWin 函数,参见代码如下:

解法二:

class Solution {
public:
bool canWin(string s) {
for (int i = -; (i = s.find("++", i + )) >= ;) {
if (!canWin(s.substr(, i) + "--" + s.substr(i + ))) {
return true;
}
}
return false;
}
};

Github 同步地址:

https://github.com/grandyang/leetcode/issues/294

类似题目:

Nim Game

Flip Game

Guess Number Higher or Lower II

Can I Win

参考资料:

https://leetcode.com/problems/flip-game-ii/

https://leetcode.com/problems/flip-game-ii/discuss/74033/4-line-Java-Solution

https://leetcode.com/problems/flip-game-ii/discuss/74010/Short-Java-and-Ruby

https://leetcode.com/problems/flip-game-ii/discuss/73962/Share-my-Java-backtracking-solution

LeetCode All in One 题目讲解汇总(持续更新中...)

[LeetCode] Flip Game II 翻转游戏之二的更多相关文章

  1. [LeetCode] Jump Game II 跳跃游戏之二

    Given an array of non-negative integers, you are initially positioned at the first index of the arra ...

  2. [LeetCode] Flip Game 翻转游戏之二

    You are playing the following Flip Game with your friend: Given a string that contains only these tw ...

  3. [LeetCode] 45. Jump Game II 跳跃游戏之二

    Given an array of non-negative integers, you are initially positioned at the first index of the arra ...

  4. [LeetCode] Reverse String II 翻转字符串之二

    Given a string and an integer k, you need to reverse the first k characters for every 2k characters ...

  5. [Swift]LeetCode294. 翻转游戏之 II $ Flip Game II

    You are playing the following Flip Game with your friend: Given a string that contains only these tw ...

  6. [LeetCode] 294. Flip Game II 翻转游戏 II

    You are playing the following Flip Game with your friend: Given a string that contains only these tw ...

  7. [LeetCode] Bulb Switcher II 灯泡开关之二

    There is a room with n lights which are turned on initially and 4 buttons on the wall. After perform ...

  8. [LeetCode] Word Pattern II 词语模式之二

    Given a pattern and a string str, find if str follows the same pattern. Here follow means a full mat ...

  9. [LeetCode] Paint House II 粉刷房子之二

    There are a row of n houses, each house can be painted with one of the k colors. The cost of paintin ...

随机推荐

  1. Aizu2224 Save your cats(最大生成树)

    https://vjudge.net/problem/Aizu-2224 场景嵌入得很好,如果不是再最小生成树专题里,我可能就想不到解法了. 对所有的边(栅栏)求最大生成树,剩下来的长度即解(也就是需 ...

  2. linux 新建用户、用户组 以及为新用户分配权限(转)

    本文转自https://www.cnblogs.com/clicli/p/5943788.html 感谢作者 Linux 系统是一个多用户多任务的分时操作系统,任何一个要使用系统资源的用户,都必须首先 ...

  3. 枚举进行位运算 枚举组合z

    枚举进行位运算--枚举组合 public enum MyEnum { MyEnum1 = , //0x1 MyEnum2 = << , //0x2 MyEnum3 = << , ...

  4. 访问天地图WMTS服务的正确姿势

    天地图2018版对天地图应用开发流程进行了升级改造,主要有两点变化: (1)接口升级为tianditu.gov.cn政府域名,支持HTTP/HTTPS协议,原有服务域名tianditu.com继续保留 ...

  5. 二进制小数及 IEEE 浮点表示

    1.二进制小数 前面这篇博客 进制间的转换  我们已经讲过了各个进制数的表示.现在我们复习一下: 进位计数制的要素: ①.数码:用来表示进制数的元素.比如二进制数的数码为:0,1.十进制数的数码为:0 ...

  6. 【C++】C++中的基本内置类型

    基本数据类型 下面这张表是C++支持的基本数据类型 类型 含义 最小尺寸 bool 布尔 未定义 char 字符 8位 wchar_t 宽字符 16位 char16_t Unicode字符 16位 c ...

  7. [转]如何实现一个malloc

    任何一个用过或学过C的人对malloc都不会陌生.大家都知道malloc可以分配一段连续的内存空间,并且在不再使用时可以通过free释放掉.但是,许多程序员对malloc背后的事情并不熟悉,许多人甚至 ...

  8. Git发生SSL certificate problem: certificate ha错误

    这两天,不知道为什么,用Git提交代码到服务器时,总出现SSL certificate problem: unable to get local issuer certificate while ac ...

  9. kafka调试工具kafkacat的使用

    一. 安装 kafkacat 是基于kafka C语言的librdkafka库的 kafka客户端,不依赖java,小巧轻便,支持主流系统.在高版本的debain.Ubuntu下可以直接apt-get ...

  10. MATLAB基础函数命令

    1. 常用命令 dir:列出当前目录下的所有文件 clc:清除命令窗 clear all:清除环境(从内存中清除所有变量) who:将内存中的当前变量以简单形式列出 close all: 关闭所有的 ...