LeetCode - 292 - Nim游戏(nim-game)

Create by jsliang on 2019-07-19 16:54:36
Recently revised in 2019-07-19 17:38:27

一 目录

不折腾的前端,和咸鱼有什么区别

| 目录 | | --- | | 一 目录 | | 二 前言 | | 三 解题 | | 四 执行测试 | | 五 LeetCode Submit | | 六 解题思路 | | 七 题外话 |

二 前言

  • 难度:简单

  • 涉及知识:迷、极小化极大

  • 题目地址:https://leetcode-cn.com/problems/nim-game/

  • 题目内容

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

三 解题

小伙伴可以先自己在本地尝试解题,再回来看看 jsliang 的解题思路。

  • 解题代码

var canWinNim = function(n) {	
  return n % 4;	
};

四 执行测试

  1. n: 4

  2. return

false

五 LeetCode Submit

✔ Accepted	
  ✔ 60/60 cases passed (68 ms)	
  ✔ Your runtime beats 93.84 % of javascript submissions	
  ✔ Your memory usage beats 5.03 % of javascript submissions (34.3 MB)

六 解题思路

所谓传奇,有可能是你触发了传说中的幸运 1

首先,我觉得我这代码应该在时间和空间上打败任何人了。但是可惜不是。

然后jsliang 是通过找规律来破解的:

123456789
xx

因为你和你的小伙伴都是极其机智的人,所以假设在你先手并且知道牌数的情况下,你一定不会让最后的数小于 3,毕竟这样你就输了(小伙伴可以一把拿走最大 3 张牌)。

同时你希望最后牌数为 4 张,并且到你的小伙伴拿牌。这样不管它怎么拿,你都赢了(拿走剩下的牌)。

有没有想到什么?是的,剩下 4 张的时候,如果小伙伴拿牌,那它肯定输,所以我们根据小伙伴的抽牌,跟他的和保持为 4 即可。(死亡轮回)

假设:

  1. 总共 5 张牌,你肯定先拿 1 张,这样小伙伴不管拿几张,你都可以将剩下的拿走。

  2. 总共 10 张牌,那么你的计算中将其除于 4,余数 2 即是你的起手拿牌数。

  3. 总数 50 张牌,那么你的计算中将其除于 4,余数 2 即是你的起手拿牌数。

  4. 总数 100 张,那么你的计算中将其除于 4,余数为 0,所以说明你不管怎么抽取,你的小伙伴一定会凑齐 4 张,到最后他一定会赢!

最后,我们就清楚了,如果这个数,刚好是 4 的倍数,我们铁定输。但是如果不是,我们必赢!

七 题外话

最后的最后,突然想起这个游戏好像我玩过,然后坑了小学同学几次零食~

小学的时候从某本数学书上看到的游戏,具体什么忘记了。


不折腾的前端,和咸鱼有什么区别!

640?wx_fmt=jpeg

jsliang 会每天更新一道 LeetCode 题解,从而帮助小伙伴们夯实原生 JS 基础,了解与学习算法与数据结构。

扫描上方二维码,关注 jsliang 的公众号,让我们一起折腾!

640?wx_fmt=png

jsliang 的文档库 由 梁峻荣 采用 知识共享 署名-非商业性使用-相同方式共享 4.0 国际 许可协议进行许可。
基于https://github.com/LiangJunrong/document-library上的作品创作。
本许可协议授权之外的使用权限可以从 https://creativecommons.org/licenses/by-nc-sa/2.5/cn/ 处获得。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值