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.
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.
本题采用回溯法,什么是回溯法呢?回溯法是可以系统地搜索原问题的所有解或者任意解,采用DFS方法进行的搜索,有剪枝函数和限界函数。本问题难点在于转换。因为有两个人进行比赛,第一个人操作完,第二个人进行判断,如果是false的话,那么第一个人就会取胜。本题还有一个难点就是添加一个Hashset来进行memorization的操作,用于存储出现重复的并且会取胜的String,代码如下:
1 public class Solution { 2 public boolean canWin(String s) { 3 if(s==null||s.length()<2) return false; 4 Set<String> set = new HashSet<String>(); 5 return canWin(s,set); 6 } 7 public boolean canWin(String s,Set<String> set){ 8 if(set.contains(s)) return true; 9 for(int i=0;i<s.length()-1;i++){ 10 if(s.startsWith("++",i)){ 11 String t = s.substring(0,i)+"--"+s.substring(i+2); 12 if(!canWin(t,set)){ 13 set.add(s); 14 return true; 15 } 16 } 17 } 18 return false; 19 } 20 }
答案做了进一步的改进,代码如下:
1 public class Solution { 2 public boolean canWin(String s) { 3 if(s==null||s.length()<2) return false; 4 Map<String,Boolean> map = new HashMap<String,Boolean>(); 5 return canWin(s,map); 6 } 7 public boolean canWin(String s,Map<String,Boolean> map){ 8 if(map.containsKey(s)) return map.get(s); 9 for(int i=0;i<s.length()-1;i++){ 10 if(s.startsWith("++",i)){ 11 String t = s.substring(0,i)+"--"+s.substring(i+2); 12 if(!canWin(t,map)){ 13 map.put(s,true); 14 return true; 15 } 16 } 17 } 18 map.put(s,false); 19 return false; 20 } 21 }