算法 - leetcode 292 Nim Game

2023-11-05

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

  • 五大常用经典算法

    五大常用算法之一 分治算法 一 基本概念 在计算机科学中 分治法是一种很重要的算法 字面上的解释是 分而治之 就是把一个复杂的问题分成两个或更多的相同或相似的子问题 再把子问题分成更小的子问题 直到最后子问题可以简单的直接求解 原问题的解即
  • 01背包问题变种:从长度为n的数组里选出m个数使和为固定值sum

    这个问题是我从leetcode上一道问题所想到的 原题 如果是从数组中选出2个数相加使之成为固定的数sum 这当然很简单 把数组中的数字遍历一遍 判断另一个数字是否也在数组中即可 代码如下 vector
  • netty handler的执行顺序(3)

    2019独角兽企业重金招聘Python工程师标准 gt gt gt 今天解决2个问题 1 handler在pipeline当中究竟是如何存储的 2 在遍历handler的过程中 会根据event的不同 调用不同的handler 这一点是如何
  • 将二叉树转为有序的双向链表

    一 题目要求 输入一棵二叉排序树 现在要将该二叉排序树转换成一个有序的双向链表 而且在转换的过程中 不能创建任何新的结点 只能调整树中的结点指针的指向来实现 include
  • Sort List

    Sort a linked list in O n log n time using constant space complexity 题目要求用 O n log n 的时间复杂度和常数的空间复杂度来进行链表排序 O nlogn 的排序算
  • 4399 C++笔试题

    1 写出一个函数 取到链表中倒数第二个节点 双链表 node getSec List mylist return mylist m tail gt m prev m prev为链表前指针 单链表 node getSec List mylis
  • Hash table and application in java

    查找的效率取决于在查找是比较的次数 次数越少效率越高 反之越低 最理想的情况是无需比较 一次存取便能找到所查找的记录 根据对应关系f找到给定值K的像f K hash function 应运而生 由此思想建的表称为hash table 集合h
  • findBug 错误修改指南

    FindBugs错误修改指南 1 EC UNRELATED TYPES Bug Call to equals comparing different types Pattern id EC UNRELATED TYPES type EC c
  • JavaScript实现数据结构 -- 链表

    文章目录 链表 链表的特点 链表和数组的区别 JS模拟链表 遍历链表 插入节点 删除节点 链表应用 删除链表中的节点 leetcode 237 思路 代码 反转链表 leetcode 206 思路 代码 链表 链表和数组一样是有多个元素组成
  • 逆波兰表达式求值(C语言实现)

    实验项目 从文本文件输入任意一个语法正确的 中缀 表达式 显示并保存该表达式 利用栈结构 把上述 中缀 表达式转换成后缀表达式 并显示栈的状态变化过程和所得到的后缀表达式 利用栈结构 对上述后缀表达式进行求值 并显示栈的状态变化过程和最终结
  • 常用的十种算法--马踏棋盘算法

    1 马踏棋盘算法介绍 马踏棋盘算法也被称为骑士周游问题 将马随机放在国际象棋的 8 8 棋盘 Board 0 7 0 7 的某个方格中 马按走棋规则 马走日字 进行移动 要求每个方格只进入一次 走遍棋盘上全部 64 个方格 2 马踏棋盘算法
  • DDP入门

    DDP 即动态动态规划 可以用于解决一类带修改的DP问题 我们从一个比较简单的东西入手 最大子段和 带修改的最大子段和其实是常规问题了 经典的解决方法是用线段树维护从左 右开始的最大子段和和区间最大子段和 然后进行合并 现在我们换一种方法来
  • SDUT--OJ《数据结构与算法》实践能力专题训练6 图论

    A 数据结构实验之图论一 基于邻接矩阵的广度优先搜索遍历 Description 给定一个无向连通图 顶点编号从0到n 1 用广度优先搜索 BFS 遍历 输出从某个顶点出发的遍历序列 同一个结点的同层邻接点 节点编号小的优先遍历 Input
  • 如何根据链表节点数据大小对链表节点进行排序

    对链表排序有两种方法 1 比较了两个节点的大小后 对指针进行改变 从而交换节点的顺序 2 比较了两个节点的大小后 只交换数据域 而不改变指针 从而交换节点的顺序 第二种办法比较简单 本文主要对第二种方法进行讲解 链表节点排序算法 采用 冒泡
  • 堆栈01--用两个栈实现队列

    堆栈01 用两个栈实现队列 jz05 题目概述 解析 参考答案 注意事项 说明 题目概述 算法说明 用两个栈来实现一个队列 完成队列的Push和Pop操作 队列中的元素为int类型 测试用例 队列先进先出 输入 1 2 输出 1 2 解析
  • 算法学习——贪心算法之币种统计

    算法描述 币种统计 单位给每一位员工发工资 精确到元 为了保证不临时换零钱 使得每个员工取款的张数最少 在取工资前统计所有员工所需要的各种票面的张数 约定票种为100 50 20 10 5 2 1元 并验证币种统计是否正确 算法思路 算法描
  • 数据结构与算法-列表(双向链表)设计及其排序算法

    0 概述 本文主要涵盖列表 双向链表 的设计及其排序算法的总结 列表是一种典型的动态存储结构 其中的数据 分散为一系列称作节点 node 的单位 节点之间通过指针相互索引和访问 为了引入新节点或删除原有节点 只需在局部调整少量相关节点之间的
  • 【试题】排列组合

    在写一个远程的代码 如果本地有M个显示器 远程有N个显示器 M lt N 依据分辨率 显示器刷新频率等要求 需要对远程的N个显示器进行最佳分辨率修改 之后 需要从N个远程显示器中选择M个 跟本地显示器进行一对一的匹配 即从 A N M N
  • 【数据结构】双链表的定义和操作

    目录 1 双链表的定义 2 双链表的创建和初始化 3 双链表的插入节点操作 4 双链表的删除节点操作 5 双链表的查找节点操作 6 双链表的更新节点操作 7 完整代码 嗨 我是 Filotimo 很高兴与大家相识 希望我的博客能对你有所帮助
  • 排序:计数排序

    一 概念 计数排序是非比较排序 是对哈希直接定址法的变形应用 二 思想 利用数组统计相同数据出现的次数 例如整型数据m出现n次 就在数组m位置记录数据为n 最后从头遍历数组打印数据即可 通俗来讲就是 数组下标即为数据 下标所指位置的值即为数

随机推荐

  • eclipse 如何创建一个Dynamic Web project (动态web项目)

    1 准备工作 eclipse的下载安装 2 创建Dynamic Web project 至此一个Dynamic web project生成完毕 项目结构为
  • Docker部署笔记

    纯手记 无解释 莫抄 目录 安装docker 启动所有容器 关闭所有容器 删除所有容器 自定义容器IP 复制 Jenkins 其他参考 Document mysql redis nginx Rabbitmq elasticsearch lo
  • 科研初体验之Linux服务器的入门使用,关于分配了Linux账号之后怎么用,以及怎么利用Linux服务器来跑我们的python代码

    前情提要 如果有人看了我之前发的乱七八糟的博客的话 应该就能了解到 我之前是计算机专业大三的学生 好不容易get到了保研的名额 前段时间就一直在操练LeetCode 到处报夏令营啊 预推免什么的 最后喜提中科院计算所的offer 我之前都不
  • 通用业务平台设计(四):灰度发布架构升级

    强烈推荐一个大神的人工智能的教程 http www captainai net zhanghan 前言 在上家公司 随着业务的不断拓展 从支持单个国家单个主体演变成支持多个国家多个主体 在演化的过程中沉淀出平台 短信 活体 push等 能力
  • LabVIEW2020编程基础:Database Toolkit 创建数据库表及字段

    LabVIEW2020编程基础 Database Toolkit数据库系列教程 1 LabVIEW2020编程基础 Database Toolkit 创建数据库表及字段 2 LabVIEW2020编程基础 Database Toolkit
  • MySQL - 各种超时时间 - 学习与探究

    1 应用场景 主要用于学习与探究MySQL各种超时时间 应用在合适的场景下 2 学习 操作 1 文档阅读 https wen geekr dev chatgpt 官方文档 其他资料 2 整理输出 2 1 是什么 MySQL中有多个超时时间
  • java自动化测试语言高级之Object 类

    java自动化测试语言高级之Object 类 文章目录 java自动化测试语言高级之Object 类 Java Object 类 Java Object 类 Java Object 类是所有类的父类 也就是说 Java 的所有类都继承了 O
  • vue项目 高德地图实现区域多个标点并通过半径距离以此点绘制多个圆(circle),动态显示隐藏圆;实现根据经纬度获取中文地址,根据地址获取经纬度;地图控件显示隐藏

    最终效果 一 需求 最近公司有这样一个需求 指定一个区域根据一个距离测算需要开放多少个门店才能覆盖整个指定区域 暂不考虑人口密集 山区等因素 大概估算 因此稍微了解了一下 高德地图的API 记录一下常用高德地图进行定位 标点 自定义标点 测
  • 优美的小程序启动页(附源码)

    优美的小程序启动页 附源码 1 看效果 2 注意点 实现这一效果其实是很简单的 首先我们要把自己设置的启动页的路径写在app jon中 注意小程序默认第一个路径是小程序加载的开始页 其次我们的页面有时会出现这种情况 这是应为在x json文
  • Mysql 将逗号隔开的属性字段数据由列转行

    Mysql 将逗号隔开的属性字段转行为行数据 Mysql 将逗号隔开的属性字段转行为行数据 场景 在开发时 我们会根据需求进行数据库表的设计 有时我们在设计数据表时无法很好的符合三大范式 原因场景的复杂性 假如时时刻刻遵顼三大范式 会增加我
  • 搭建私有YUM仓库_及_内网镜像站

    搭建私有YUM仓库 及 内网镜像站 搭建私有YUM仓库 自己定制的rpm包 私有yum仓库环境系统版本 centos7 4 IP 192 168 1 47 最好能上公网 私有yum仓库服务端配置 第一 创建使用yum仓库存放路径 mkdir
  • 爱心循环java代码

    package 对阳子心动 public class aixindaima public static void main String args throws InterruptedException int count 0 for fl
  • 函数、对象在内存中存在形式

    一 php底层内存分区 php将内存分为5个区 堆区一般存对象 栈区一般存基本数据类型 普通变量 和函数 全局区存全局变量和静态变量 常量区存常量 代码区存代码 二 函数调用时栈区变化 这是一个简单的递归函数示例 当主函数调用counts函
  • 服务器IP装系统,服务器 安装系统 自动设置ip

    服务器 安装系统 自动设置ip 内容精选 换一换 在移动设备上正确安装APP后 就可以通过APP登录NetEco服务器 在裸金属服务器发放过程中 普通裸金属服务器的操作系统需要从云端下载 安装 下载过程会消耗较长时间 基于云硬盘的裸金属服务
  • python 画正弦曲线

    要画正弦曲线先设定一下x的取值范围 从0到2 要用到numpy模块 numpy pi 表示 numpy arange 0 2 0 01 从0到2 以0 01步进 令 x numpy arange 0 2 numpy pi 0 01 y nu
  • 进程、线程和协程的理解

    进程 线程和协程的理解 进程 线程和协程之间的关系和区别也困扰我一阵子了 最近有一些心得 写一下 进程拥有自己独立的堆和栈 既不共享堆 亦不共享栈 进程由操作系统调度 线程拥有自己独立的栈和共享的堆 共享堆 不共享栈 线程亦由操作系统调度
  • 模拟模态对话框的DIV

    最近项目中用到一个模拟模态对话框的DIV的实现 有两个层 下面的层是半透明的 将遮盖整个窗口 上面的层则用于用户输入信息 这里是一个简单的模仿 以下是页面代码 table tr td td tr table
  • unity3D游戏开发三之unity编辑器二

    unity3D游戏开发三之unity编辑器二 分类 unity3d开发 2014 04 06 12 03 264人阅读 评论 0 收藏 举报 unity3d 游戏开发 编辑器 对象 下面我们介绍下GameObject 游戏对象 物体 通过游
  • uniapp 使用uView框架 upload组件上传前压缩图片

    根据Uview官方文档所说 若是小程序和app项目 上传使用压缩图片 可以配置u upload组件的sizeType属性为 compress 但这对H5是无效的 在实际开发中 图片压缩上传经常是一个必要的需求 所以本篇文章主要讲的是在H5项
  • 算法 - leetcode 292 Nim Game

    算法 leetcode 292 Nim Game 一丶题目 你和你的朋友 两个人一起玩 Nim 游戏 桌子上有一堆石头 每次你们轮流拿掉 1 3 块石头 拿掉最后一块石头的人就是获胜者 你作为先手 你们是聪明人 每一步都是最优解 编写一个函