博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[LeetCode] Flip Game II
阅读量:5014 次
发布时间:2019-06-12

本文共 2624 字,大约阅读时间需要 8 分钟。

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 (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, 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
states = gameStates(s); 5 if (states.empty()) return false; 6 return spragueGrundy(states) != 0; 7 } 8 private: 9 vector
gameStates(string& s) {10 vector
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
& 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
& states) {28 int m = *max_element(states.begin(), states.end());29 vector
sg(m + 1, 0);30 for (int l = 2; l <= m; l++) {31 unordered_set
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 };

 

转载于:https://www.cnblogs.com/jcliBlogger/p/4886741.html

你可能感兴趣的文章
MySQL服务启动:某些服务在未由其他服务或程序使用时将自动停止
查看>>
软件工程第四周作业 - 单元测试
查看>>
KNN与SVM对比&SVM与逻辑回归的对比
查看>>
php 现在拓展地址
查看>>
【Java并发编程】之十六:深入Java内存模型——happen-before规则及其对DCL的分析(含代码)...
查看>>
团队个人冲刺第三天
查看>>
unit
查看>>
2017-10-17 NOIP模拟赛2
查看>>
How to install ia32-libs in Ubuntu 14.04 LTS (Trusty Tahr)
查看>>
ACM/ICPC 之 模拟 (HNUOJ 13391-换瓶模拟)
查看>>
JavaWeb学习——JSP基础
查看>>
Eclipse tomcat server 无法添加项目
查看>>
黑寡妇黄飞鸿
查看>>
leetcode 217 Contains Duplicate 数组中是否有重复的数字
查看>>
The Ctrl & CapsLock `problem'
查看>>
MyBatis学习总结(二)——使用MyBatis对表执行CRUD操作
查看>>
linux故障判断
查看>>
Leetcode 23. Merge k Sorted Lists(python)
查看>>
Java进阶知识点6:并发容器背后的设计理念 - 锁分段、写时复制和弱一致性
查看>>
Makefile ===> Makefile 快速学习
查看>>