BiruLyu
8/12/2017 - 9:12 PM

294. Flip Game II(#).java

public class Solution {
    public boolean canWin(String s) {
        if (s == null || s.length() < 2) {
            return false;
        }
        HashMap<String, Boolean> winMap = new HashMap<String, Boolean>();
        return helper(s, winMap);
    }

    public boolean helper(String s, HashMap<String, Boolean> winMap) {
        if (winMap.containsKey(s)) {
            return winMap.get(s);
        }
        for (int i = 0; i < s.length() - 1; i++) {
            if (s.startsWith("++", i)) {
                String t = s.substring(0, i) + "--" + s.substring(i+2);
                if (!helper(t, winMap)) {
                    winMap.put(s, true);
                    return true;
                }
            }
        }
        winMap.put(s, false);
        return false;
    }
}
public class Solution {
    public boolean canWin(String s) {
        if (s.length() < 2) {
            return false;
        }
        for (int i = 1; i < s.length(); i++) {
            if (s.charAt(i - 1) == '+' && s.charAt(i) == '+') {
                String tmp = s.substring(0, i - 1) + "--" + s.substring(i + 1, s.length());
                if (!canWin(tmp)) {
                    return true;
                }
            }
            
        }
        return false;
    }
}
public class Solution {
	public boolean canWin(String s) {
		if (s == null)
			return false;
		return canWin(s.toCharArray());
	}

	private boolean canWin(char[] chars) {
		for (int i = 0; i < chars.length - 1; i++) {
			if (chars[i] == '+' && chars[i + 1] == '+') {
				chars[i] = chars[i + 1] = '-';
				boolean win = !canWin(chars);
				chars[i] = chars[i + 1] = '+'; // backtrack.
				if (win)
					return true;
			}
		}
		return false;
	}
 
}
public class Solution {
    
    public boolean canWin(String s) {
        int curLen = 0, maxLen = 0;
        List<Integer> list = new ArrayList<>();
        for (int i = 0; i < s.length(); i++) {
            if (s.charAt(i) == '+') curLen++;
            if (s.charAt(i) == '-' || i == s.length() - 1) {
                if (curLen >= 2)  list.add(curLen);
                maxLen = Math.max(maxLen, curLen);
                curLen = 0;
            }
        }
        int[] g = new int[maxLen + 1];
        for (int len = 2; len <= maxLen; len++) {
            Set<Integer> set = new HashSet<>();
            for (int first = 0; first < len / 2; first++) {
                int second = len - first - 2;
                set.add(g[first] ^ g[second]);
            }
            g[len] = FMV(set);
        }
        int res = 0;
        for (int i : list) res ^= g[i];
        return res != 0;
    }
    private int FMV(Set<Integer> set) {
        int i = 0;
        for (; i < set.size(); i++) {
            if (!set.contains(i)) break;
        }
        return i;
    }
}
public class Solution {
    private List<Integer> canFlip(char[] str) {
        List<Integer> res = new ArrayList<>();
        for (int i = 0; i < str.length - 1; i++) {
            if (str[i] == '+' && str[i + 1] == '+') {
                res.add(i);
            }
        }
        return res;
    }
    private boolean backtracking(char[] str) {
        List<Integer> choices = canFlip(str);
        if (choices.size() == 0) return false;
        for (int i : choices) {
            str[i] = '-';
            str[i + 1] = '-';
            if (!backtracking(str)) {
                str[i] = '+';
                str[i + 1] = '+';
                return true;
            }
            str[i] = '+';
            str[i + 1] = '+';
        }
        return false;
    }
    public boolean canWin(String s) {
        return backtracking(s.toCharArray());
    }
}