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.
根据题目的意思,就是观察所有的结果中,有没有能保证第一个先翻转的能够有赢得可能性的一个字串。只要有一种能赢的可能,就是True。
class Solution(object):
def canWin(self, s):
"""
:type s: str
:rtype: bool
"""
for i in range(len(s) - 1): # 寻找所有的翻转可能
if s[i:i+2] == "++":
current = s[0:i] + "--" + s[i+2:] # 把找到的++变成--
if not self.canWin(current): # 看当前的字串是否存在边界,没有++了
return True # 对手不能赢,那就是当前翻转的赢了
return False # loop中没有返回,不能赢,当前翻转的输了
用dictionary存已经出现过的String,和返回的boolean值,可以减少重复判定
class Solution(object):
_dic = {}
def canWin(self, s):
"""
:type s: str
:rtype: bool
"""
dic = self._dic
if s not in dic:
for i in range(len(s) - 1):
if s[i:i+2] == "++":
current = s[0:i] + "--" + s[i+2:]
if not self.canWin(current):
dic[s] = True
if s not in dic:
dic[s] = False
return dic[s]
上面的方法浓缩到一行,可以用any 方法。Tip中会有对any的补充。
class Solution(object):
_dic = {}
def canWin(self, s):
"""
:type s: str
:rtype: bool
"""
dic = self._dic
if s not in dic:
dic[s] = any([s[i:i+2] == "++" and not self.canWin(s[:i] + "--" + s[i+2:]) for i in range(len(s) - 1)]) # 替换成两个--,也可以缩写成替换成一个-,效果是一样的。
return dic[s]
=======
any function
any([list comprehension])
any((generator comprehension)) 比上面的快很多
l = [x for x in range(100000000)]
ll = (x for x in range(100000000))
import time
time1 = time.time()
print any(l)
time2 = time.time()
print any(ll)
time3 = time.time()
print time2 - time1 # 8.10623168945e-06
print time3 - time2 # 2.86102294922e-06