[LeetCode] Flip Game II

简介: Problem Description: You are playing the following Flip Game with your friend: Given a string that contains only these two characters: + and -, you a...

Problem Description:

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.

For example, given s = "++++", return true. The starting player can guarantee a win by flipping the middle "++" to become "+--+".

Follow up:
Derive your algorithm's runtime complexity.


The simplest solution that I have found is here (refer to the first paragraph for explanations of the idea and the Java code). I rewrite it in C++.

The idea is very straightforward: if you can make s non-winnable by a move, then you will win.

1 class Solution {
2 public:
3     bool canWin(string s) {
4         for (int i = -1; (i = s.find("++", i + 1)) >= 0; )
5             if (!canWin(s.substr(0, i) + '-' + s.substr(i+2)))
6                 return true;
7         return false;
8     }
9 };

If you are interested to learn more, this post shares a more sophisticated solution using game theory (it reduces the running time to 0 seconds!). The code is restructured as below.

 1 class Solution {
 2 public:
 3     bool canWin(string s) {
 4         vector<int> states = gameStates(s);
 5         if (states.empty()) return false;
 6          return spragueGrundy(states) != 0;
 7     }
 8 private:
 9     vector<int> gameStates(string& s) {
10         vector<int> states;
11         int n = s.length(), c = 0;
12         for (int i = 0; i < n; i++) {
13             if (s[i] == '+') c++;
14             if (i == n - 1 || s[i] == '-') {
15                 if (c >= 2) states.push_back(c);
16                 c = 0;
17             }
18         }
19         return states;
20     }
21     int firstMissingNumber(unordered_set<int>& st) {
22         int m = st.size();
23         for (int i = 0; i < m; i++)
24             if (!st.count(i)) return i;
25         return m;
26     }
27     int spragueGrundy(vector<int>& states) {
28         int m = *max_element(states.begin(), states.end());
29         vector<int> sg(m + 1, 0);
30         for (int l = 2; l <= m; l++) {
31             unordered_set<int> st;
32             for (int l1 = 0; l1 < l / 2; l1++) {
33                 int l2 = l - l1 - 2;
34                 st.insert(sg[l1] ^ sg[l2]);
35             }
36             sg[l] = firstMissingNumber(st);
37         }
38         int v = 0;
39         for (int state : states) v ^= sg[state];
40         return v;
41     }
42 };

 

目录
相关文章
LeetCode 390. Elimination Game
给定一个从1 到 n 排序的整数列表。 首先,从左到右,从第一个数字开始,每隔一个数字进行删除,直到列表的末尾。 第二步,在剩下的数字中,从右到左,从倒数第一个数字开始,每隔一个数字进行删除,直到列表开头。 我们不断重复这两步,从左到右和从右到左交替进行,直到只剩下一个数字。 返回长度为 n 的列表中,最后剩下的数字。
101 0
LeetCode 390. Elimination Game
LeetCode 292. Nim Game
你和你的朋友,两个人一起玩 Nim游戏:桌子上有一堆石头,每次你们轮流拿掉 1 - 3 块石头。 拿掉最后一块石头的人就是获胜者。你作为先手。 你们是聪明人,每一步都是最优解。 编写一个函数,来判断你是否可以在给定石头数量的情况下赢得游戏。
73 0
LeetCode 292. Nim Game
|
存储 算法
LeetCode 289. Game of Life
如果活细胞周围八个位置的活细胞数少于两个,则该位置活细胞死亡; 如果活细胞周围八个位置有两个或三个活细胞,则该位置活细胞仍然存活; 如果活细胞周围八个位置有超过三个活细胞,则该位置活细胞死亡; 如果死细胞周围正好有三个活细胞,则该位置死细胞复活;
75 0
LeetCode 289. Game of Life
|
算法 索引
LeetCode 55. Jump Game
给定一个非负整数数组,您最初定位在数组的第一个索引处。 数组中的每个元素表示该位置的最大跳转长度。 确定您是否能够到达最后一个索引。
89 0
LeetCode 55. Jump Game
|
算法 索引
LeetCode 45. Jump Game II
给定一个非负整数数组,初始位置在索引为0的位置,数组中的每个元素表示该位置的能够跳转的最大部署。目标是以最小跳跃次数到达最后一个位置(索引)。
78 0
LeetCode 45. Jump Game II
LeetCode contest 200 5476. 找出数组游戏的赢家 Find the Winner of an Array Game
LeetCode contest 200 5476. 找出数组游戏的赢家 Find the Winner of an Array Game
|
决策智能
LeetCode之Nim Game
LeetCode之Nim Game
120 0
|
C++
LeetCode 289 Game of Life(生命游戏)(Array)
版权声明:转载请联系本人,感谢配合!本站地址:http://blog.csdn.net/nomasp https://blog.csdn.net/NoMasp/article/details/52122735 翻译 根据维基百科的文章介绍:“Game of Life,简称为Life,是一个被英国数学家John Conway在1970年提出的细胞自动分裂器。
1638 0
LeetCode - 45. Jump Game II
45. Jump Game II  Problem's Link  ---------------------------------------------------------------------------- Mean:  给定一个数组a,玩家的初始位置在idx=0,玩家需要到达的位置是idx=a.
937 0