1.问题描述

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 the stones.Both of you are very clever and have optimal strategies for the game.

Write a function to determine whether you can win the game given the number of stones in the heap.

你和你的朋友,两个人一起玩 Nim 游戏:

桌子上有一堆石头。
你们轮流进行自己的回合,你作为先手。
每一回合,轮到的人拿掉 1 - 3 块石头。
拿掉最后一块石头的人就是获胜者。
假设你们每一步都是最优解。请编写一个函数,来判断你是否可以在给定石头数量为 n 的情况下赢得游戏。如果可以赢,返回 true;否则,返回 false 。

注意,石头的堆的数量为偶数,所以你们两人拿走的堆数一定是相同的。
石头的总数为奇数,也就是你们最后不可能拥有相同多的石头,一定有胜负之分。

2.解法1

这个问题,看上去有点像斐波那契数列的问题。我们先用斐波那契数列的思路来解一下。

    private static boolean winGamev1(int n) {// 最后一个没了,说明最后一个被对手拿到了,你输了。// 如果最后剩的个数小于4个,即还剩1个,2个或者3个,你都赢了。if (n == 0) {return false;} if (n < 4) {return true;}for(int i=1; i<=3; i++) {//对方不管拿走 1 个,2 个,3 个, 你都可以获胜if (winGamev1(n-i-1) && winGamev1(n-i-2) && winGamev1(n-i-3)) {return true;}}return false;}

上面的代码可以完成相应的功能。但是很明显,效率很低,因为会有递归调用方法的问题,当n变大以后,复杂度会非常高。

3.解法2

遇到这种复杂的问题,我们经常使用的一种方式是反推法。
如果最后一轮要自己获胜,最后剩余的石头需要是1颗,2颗,或者3颗,这样能一次性拿完。
那么,等对手最后一次拿的时候,如果剩下的是4颗石头,那么不管他拿1颗,2颗,还是3颗,剩下的石头肯定是在1-3颗。
那如何使对手最后一次拿的时候还剩4颗石头呢?如果我们能使我们自己选择的时候还剩5颗,6颗,或者7颗石头,这样的话能保证对手拿的时候还剩4颗石头。

所以这么一直推导下去会发现,只要谁拿石子的时候,是4的倍数,那就一定会输。

所以最终的解法非常简单

    private static boolean winGamev2(int n) {return n % 4 != 0;}

只要n % 4 != 0,那么先手一定能获胜。

leetcode 292 NimGame相关推荐

  1. LeetCode 292 Nim Game

    LeetCode 292 Nim Game https://leetcode.com/problems/nim-game/ 当能被4整除时,才会输. bool canWinNim(int n) {re ...

  2. leetcode 292. Nim Game | 292. Nim 游戏(DP->数学推理)

    题目 https://leetcode-cn.com/problems/nim-game/ 题解 本题实际上是一个需要分析的数学题.如果第一时间没有发现规律的话,可以尝试先用递归法,暴力输出前几个,观 ...

  3. LeetCode 292. Nim Game

    292. Nim Game 尼姆游戏 You are playing the following Nim Game with your friend: 您正在和您的朋友玩以下NIM游戏: There ...

  4. Java实现 LeetCode 292 Nim游戏

    292. Nim 游戏 你和你的朋友,两个人一起玩 Nim 游戏:桌子上有一堆石头,每次你们轮流拿掉 1 - 3 块石头. 拿掉最后一块石头的人就是获胜者.你作为先手. 你们是聪明人,每一步都是最优解 ...

  5. Leetcode 292. Nim 游戏 解题思路及C++实现

    方法一:规律 解题思路: n从1开始增加,可以发现,当 n 是 4 的倍数的时候,就是false. class Solution { public:bool canWinNim(int n) {ret ...

  6. Leetcode 博弈论先手必胜解题思路(Leetcode 292/877)

    就一个一个的枚举,1-3块手头,先手必胜,4块手头,先手必负, 5个石头,拿一个,让对手变成4个,那么必胜. 8个石头,不管怎么拿,必负. 因此可归纳出4的倍数的石头时,都必输. 这种是最简单的博弈论 ...

  7. LeetCode 292 Nim Game(Nim游戏)

    翻译 你正在和你的朋友们玩下面这个Nim游戏:桌子上有一堆石头,每次你从中去掉1-3个.谁消除掉最后一个石头即为赢家.你在取出石头的第一轮.你们中的每一个人都有着聪明的头脑和绝佳的策略.写一个函数来确 ...

  8. 开启LeetCode之路

    终于有时间开始每天坚持做LeetCode题,博主现在以在CSDN上撰写解题思路为自我监督方式,坚持每天将当天的题目的解题思路记录下来. LeetCode刷题路线:博主将计划按tag顺序做题,先以简单和 ...

  9. LeetCode题解目录

    最新更新于2020.11.27 前往LeetCode主页. 前往GitHub源码.(服务器原因,暂停同步.) 前往码云主页. 已解决 456/1878 - 简单353 中等 90 困难 13 2020 ...

  10. 《数据结构与算法之美》学习汇总

    此篇文章是对自己学习这门课程的一个总结和课后的一些练习,做一个汇总,希望对大家有帮助.本人是半路程序员,2018年2月开始学习C++的,下面的代码基本都是C++11版本的,代码有错误的地方请不吝留言赐 ...

最新文章

  1. selenium+Headless Chrome实现不弹出浏览器自动化登录
  2. oracle text db2,从Oracle 到DB2(一)
  3. java字符动画思路_【轻松一刻】Java制作字符动画
  4. 搭建MSSM框架(Maven+Spring+Spring MVC+MyBatis)
  5. 【LeetCode笔记】剑指 Offer 03. 数组中重复的数字(Java、哈希表、原地算法)
  6. 《Android/OPhone开发完全讲义》连载(7):使用SharedPreferences存取复杂数据
  7. python3 ascii转utf8_ASCII、Unicode、UTF-8以及Python3编码问题
  8. QT--学习疑惑探索
  9. Java 延时常见的几种方法
  10. 数据结构-阶段性理解
  11. FOR XML PATH 应用及其反向分解
  12. 如何用甘特图进行项目进度管理
  13. 点云学习笔记16——pcl点云可视化
  14. 带通滤波器是什么,它的原理是什么
  15. 坚持学习,坚持阅读,坚持思考
  16. 百度大脑开放日走进厦门 全面解析AI如何赋能企业服务智能化
  17. 阅读小结:The Unreasonable Effectiveness of Noisy Data for Fine-Grained Recognition
  18. 火狐浏览器的下载安装
  19. 【CSDN英雄会】囯炬CEO张代浩:做写架构的人,做制定游戏规则的人
  20. 艾永亮:英语教育往事:一部商业的进化史

热门文章

  1. 第二章 算法 (大话数据结构)
  2. LVS 三种工作模式
  3. docker管理神器—kubernetes—直接路由篇
  4. 《应用时间序列分析:R软件陪同》——2.11 习题
  5. Effective C++ 之 Item 5:了解C++默默编写并调用哪些函数
  6. Cap01_信息化和信息系统
  7. 加速nginx: 开启gzip
  8. 面向对象思想,简单实例
  9. Linux中利用NFS实现飞鸽传书
  10. Java IO流学习总结(转)