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. .net core使用配置文件

    .net core使用配置文件 在 .net core中,配置文件的读取是通过IConfiguration来提供的,程序集是Microsoft.Extensions.Configuration,对应的 ...

  2. 提升SQLite数据插入效率低、速度慢的方法(转)

    前言 SQLite数据库由于其简单.灵活.轻量.开源,已经被越来越多的被应用到中小型应用中.甚至有人说,SQLite完全可以用来取代C语言中的文件读写操作.因此我最近编写有关遥感数据处理的程序的时候, ...

  3. spring @Transactional 事务注解

    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.SERIALIZABLE, rollbackFor = ...

  4. grid - 隐式命名网格线名称

    1.隐式的指定网格线反向指定了隐式的网格区域名称,命名的网格区域隐式的命名了网格线名称. 指定网格区域会给网格区域边线添加隐式的网格线名称.这些网格线的命名是基于网格区域来命名,只是在网格区域名称的后 ...

  5. php的Allowed memory size of 134217728 bytes exhausted问题解决办法

    php的Allowed memory size of 134217728 bytes exhausted问题解决办法 报错: Fatal error: Allowed memory size of 1 ...

  6. MySQL利用xtrabackup在线修复或新增从库

    如果数据库的数据量很大,表大小有几十个G,利用mysqldump导出备份会消耗非常长的时间,会对数据库产生不稳定风险,这时可以利用xtrabackup工具在线复制主库文件,利用复制出来的主库文件可以修 ...

  7. 基于properties文件的Spring Boot多环境切换

    当我们使用properties文件作为Spring Boot的配置文件而不是yaml文件时,怎样实现多环境使用不同的配置信息呢?     在Spring Boot中,多环境配置的文件名需要满足appl ...

  8. kali 安装google chrome浏览器(离线手动)

    一.官网下载安装包 需要在google官网下载chrome安装包,安装时请仔细选择安装包,.deb的安装包适用于Debian/Ubuntu系统,.rpm适用于 Fedora/openSUSE系统. k ...

  9. Asp.Net Nuget常用命令

    1.安装 Install-Package EntityFramework //ef Install-Package EntityFramework.zh-Hans //ef中文

  10. EntityFramework安装失败

    PM> Install-Package EntityFramework正在尝试收集与目标为“.NETFramework,Version=v4.0”的项目“ConsoleApplication1” ...