算法 - leetcode 292 Nim Game

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

原文地址:https://www.cnblogs.com/timfruit/p/11616262.html

时间: 2024-10-11 11:14:04

算法 - leetcode 292 Nim Game的相关文章

[LeetCode]-292. Nim Game(Easy)(C + 尼姆游戏)

292. Nim Game My Submissions Question Editorial Solution Total Accepted: 67907 Total Submissions: 128306 Difficulty: Easy You are playing the following Nim Game with your friend: There is a heap of stones on the table, each time one of you take turns

【算法功底】LeetCode 292 Nim Game

You are playing the following Nim Game with your friend: There is a heap of stones on the table, each time one of you take turns to remove 1 to 3 stones. The one who removes the last stone will be the winner. You will take the first turn to remove th

[leetcode] 292. Nim Game 解题报告

You are playing the following Nim Game with your friend: There is a heap of stones on the table, each time one of you take turns to remove 1 to 3 stones. The one who removes the last stone will be the winner. You will take the first turn to remove th

LeetCode 292 Nim Game(Nim游戏)

翻译 你正在和你的朋友们玩以下这个Nim游戏:桌子上有一堆石头.每次你从中去掉1-3个.谁消除掉最后一个石头即为赢家.你在取出石头的第一轮. 你们中的每个人都有着聪明的头脑和绝佳的策略.写一个函数来确定对于给定的数字是否你能够赢得这场比赛. 比如,假设堆中有4个石头,那么你永远也无法赢得比赛:不管你移除了1.2或3个石头,最后一个石头都会被你的朋友所移除. 原文 You are playing the following Nim Game with your friend: There is a

[LeetCode] 292. Nim Game_Easy tag: Math

You are playing the following Nim Game with your friend: There is a heap of stones on the table, each time one of you take turns to remove 1 to 3 stones. The one who removes the last stone will be the winner. You will take the first turn to remove th

&lt;LeetCode OJ&gt; Nim Game【292】

292. Nim Game My Submissions Question Total Accepted: 30675 Total Submissions: 61031 Difficulty: Easy You are playing the following Nim Game with your friend: There is a heap of stones on the table, each time one of you take turns to remove 1 to 3 st

292. Nim Game (取物游戏) by Python

292. Nim Game 题目: You are playing the following Nim Game with your friend: There is a heap of stones on the table, each time one of you take turns to remove 1 to 3 stones. The one who removes the last stone will be the winner. You will take the first

292. Nim Game(C++)

292. Nim Game(C++) You are playing the following Nim Game with your friend: There is a heap of stones on the table, each time one of you take turns to remove 1 to 3 stones. The one who removes the last stone will be the winner. You will take the firs

前端与算法 leetcode 28.实现 strStr()

# 前端与算法 leetcode 28.实现 strStr() 题目描述 28.移除元素 概要 这道题的意义是实现一个api,不是调api,尽管很多时候api的速度比我们写的快(今天这个我们可以做到和indexOf一样快),但我们还是要去了解api内实现的原理,在我们所熟悉的v8引擎中,indexOf使用了kmp和bm两种算法,在主串长度小于7时使用kmp,大于7的时候使用bm,bf咱就不说了哈,那个其实就是爆破算法, 提示 数据结构,kmp,bm 解析 kmp算法的核心其实就是动态规划,明确了