• 算法


    算法 - leetcode 292 Nim Game

     一丶题目

    你和你的朋友,两个人一起玩 Nim 游戏:桌子上有一堆石头,每次你们轮流拿掉 1 - 3 块石头。 拿掉最后一块石头的人就是获胜者。你作为先手。
    
    你们是聪明人,每一步都是最优解。 编写一个函数,来判断你是否可以在给定石头数量的情况下赢得游戏。
    
    
    输入: 4
    输出: false 
    解释: 如果堆中有 4 块石头,那么你永远不会赢得比赛;
         因为无论你拿走 1 块、2 块 还是 3 块石头,最后一块石头总是会被你的朋友拿走。

    二丶思路

      1) 先尝试使用暴力解决--递归

      

    class Solution {
        public boolean canWinNim(int n) {
            if(n<=0){
                return false;
            }
            if(n<=3){
                return true;
            }
            if(!friendCanWinNim(n-1)){ //拿1块
                return true;
            }
            if(!friendCanWinNim(n-2)){ //拿2块
                return true;
            }
            if(!friendCanWinNim(n-3)){ //拿3块
                return true;
            }
            return false;
        }
    
        //朋友拿, 朋友是否可以赢
        private boolean friendCanWinNim(int n){
            if(n<=0){
                return false;
            }
            if(n<=3){
                return true;
            }
            if(!canWinNim(n-1)){ //拿1块
                return true;
            }
            if(!canWinNim(n-2)){ //拿2块
                return true;
            }
            if(!canWinNim(n-3)){ //拿3块
                return true;
            }
            return false;
        }
    }

      2) 出现超时的现象,缓存中间结果

    class Solution {
        Map<Integer, Boolean> resultMap =new HashMap<Integer, Boolean>(); //结果
        
        public boolean canWinNim(int n) {
            if(n<=0){
                return false;
            }
            if(n<=3){
                return true;
            }
            if(results[n]!=null){
                return results[n];
            }
    
            boolean result=false;
            if(!friendCanWinNim(n-1)){ //拿1块
                result=true;
                resultMap.put(n, result);return result;
            }
            if(!friendCanWinNim(n-2)){ //拿2块
                result=true;
                resultMap.put(n, result);return result;
            }
            if(!friendCanWinNim(n-3)){ //拿3块
                result=true;
                resultMap.put(n, result);return result;
            }
    
            result=false;
            resultMap.put(n, result);return result;
        }
    
        //朋友拿, 朋友是否可以赢
        private boolean friendCanWinNim(int n){
            if(n<=0){
                return false;
            }
            if(n<=3){
                return true;
            }
            if(!canWinNim(n-1)){ //拿1块
                return true;
            }
            if(!canWinNim(n-2)){ //拿2块
                return true;
            }
            if(!canWinNim(n-3)){ //拿3块
                return true;
            }
            return false;
        }
    }

      3) 递归过大, 出现栈溢出异常, 将递归改成for循环 (类似动态规划)

    class Solution {
        Map<Integer, Boolean> resultMap =new HashMap<Integer, Boolean>(); //缓存先手的结果
        public boolean canWinNim(int n) {
           if(n<=0){
                return false;
            }
            // 初始化
            resultMap.put(1, true);
            resultMap.put(2, true);
            resultMap.put(3, true);
    
            boolean result1, result2, result3;
            for(int i=4;i<=n;i++){
                // 拿1块
                result1=resultMap.get(i-1);
    
                // 拿2块
                result2=resultMap.get(i-2);
    
                // 拿3块
                result3=resultMap.get(i-3);
    
                if(!result1 || !result2 || !result3){
                    resultMap.put(i, true);
                }else {
                    resultMap.put(i, false);
                }

           System.out.println(i+" -> "+resultMap.get(i)); }
    return resultMap.get(n); } }

      4) 仍然出现超时, (打印中间结果可发现规律 T_T 这里看了别人的解释)

    class Solution {
        public boolean canWinNim(int n) {
            //规律题
            // 3+1  必输
            return n%(3+1)!=0;
        }
    }
    人生没有彩排,每一天都是现场直播
  • 相关阅读:
    Mybatis集成dbcp-java.lang.AbstractMethodError: Method org/apache/commons/dbcp/DelegatingResultSet.isClosed()Z is abstract
    Word 错误提示“此功能看似已中断,并需要修复” 解决
    解决 org.springframework.context.annotation.ConflictingBeanDefinitionException
    IDEA中的JAVA WEB项目启动报错的定位方法
    Oracle数据库中包含CLOB字段表的导出和导入
    idea terminal修改为gitbash多彩
    企业微信如何发红包 企业微信向个人发红包 企业微信群无法发红包 企业微信无法发红包 企业微信无法发红包如何解决
    vue项目中使用ts(typescript)入门教程
    svg / d3-force 中如何给link的label文字加底色
    svg 如何使用滤镜给文字加底色
  • 原文地址:https://www.cnblogs.com/timfruit/p/11616262.html
Copyright © 2020-2023  润新知