zoukankan      html  css  js  c++  java
  • 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.

    The idea is try to replace every "++" in the current string s to "--" and see if the opponent has the chance to win or not, if the opponent is guaranteed to lose, great, we win!

    For the time complexity, here is what I thought, let's say the length of the input string s is n, there are at most n - 1 ways to replace "++" to "--" (imagine s is all "+++..."), once we replace one "++", there are at most (n - 2) - 1 ways to do the replacement, it's a little bit like solving the N-Queens problem, the time complexity is (n - 1) x (n - 3) x (n - 5) x ..., so it'sO(n!!)double factorial.

    public class Solution {
        public boolean canWin(String s) {
            if (s==null || s.length()<=1) return false;
            for (int i=0; i<s.length()-1; i++) {
                if (s.charAt(i)=='+' && s.charAt(i+1)=='+' && !canWin(s.substring(0,i) + "--" +     
                                                                                     s.substring(i+2))) 
                    return true;
            }
            return false;
        }
    }
    

    Better Solution:  (205ms -> 19ms)

     but the time complexity of the backtracking method is high. During the process of searching, we could encounter duplicate computation as the following simple case.

    One search path:

    Input s = "++++++++"

    Player 0: "--++++++"

    Player 1: "----++++"

    Player 0: "----+--+"

    Player0 can win for the input string as "----++++".

    Another search path:

    Player 0: "++--++++"

    Player 1: "----++++"

    Player 0: "----+--+"

    (Duplicate computation happens. We have already known anyone can win for the

    input string as "----++++".)

    Use a HashMap to avoid duplicate computation

    Key : InputString.

    Value: can win or not.

    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;
    }
    

      只要任何一步能让下一步的对手false, 就返回ture, 不然没有任何一步, 就返回false, 像下棋一样

  • 相关阅读:
    delphi利用文件内存共享的简单小说阅读器
    Delphi中共享内存学习
    JavaWeb初学者配置数据库连接报错(此处是MSSQL)
    Delphi的Json学习之一
    Delphi记录类型指针的使用
    汇编——段寄存器
    SQL 标量函数-----日期函数 day() 、month()、year() 转载
    项目一总结 滚动监听
    一阶段项目总结 导航栏 滚动监听固定
    简单的 js手写轮播图
  • 原文地址:https://www.cnblogs.com/apanda009/p/7395828.html
Copyright © 2011-2022 走看看