[LeetCode] 294. Flip Game II 翻轉游戲之二


 

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 = 1; i < s.size(); ++i) {
            if (s[i] == '+' && s[i - 1] == '+' && !canWin(s.substr(0, i - 1) + "--" + s.substr(i + 1))) {
                return true;
            }
        }
        return false;
    }
};

 

第二種解法和第一種解法一樣,只是用 find 函數來查找 ++ 的位置,然后把位置賦值給i,然后還是遞歸調用 canWin 函數,參見代碼如下:

 

解法二:

class Solution {
public:
    bool canWin(string s) {
        for (int i = -1; (i = s.find("++", i + 1)) >= 0;) {
            if (!canWin(s.substr(0, i) + "--" + s.substr(i + 2))) {
                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 題目講解匯總(持續更新中...)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM