LeetCode 292: Nim Game (Nim游戏)

LeetCode 292: Nim Game (Nim游戏)

原题目:

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.
Write a function to determine whether you can win the game given the number of stones in the heap.
For example, if there are 4 stones in the heap, then you will never win the game: no matter 1, 2, or 3 stones you remove, the last stone will always be removed by your friend.

题目大意:

你和你的朋友要玩Nim游戏,游戏规则如下:
1. 地上有一堆石子,你和你的朋友依次可以从中拿走1到3枚;
2. 谁在最后一次将地上的石子拿完就是游戏的胜者;
3. 游戏开始时,你先拿石子;
4. 你们俩都非常聪明,并且都会玩这个游戏的最优策略。
写一个函数来判定你是否可以在游戏中获胜。例如,如果地上有4枚石子,无论你在首次拿走其中的1,2 或者3枚,最后的石子剩下的石子都会被你的朋友一次拿完,也就是说你不可能胜。

题目分析:

Nim游戏是博弈论中最经典的模型,针对本题目中的假设条件,我进行了如下分析:
1. 由于是我先拿石子,所以如果石子是1,2或3枚,那么我必胜;
2. 如果石子的数量n >=4, 那么我第一次是不能拿完的, 我能不能在下一次拿完取决于朋友在拿1, 2,3枚石子之后的情况,如果朋友在拿走1, 2 或者3枚的情况都不能取胜,那么我就能取胜,否则朋友就取胜了,这其实是一个递归。该递归公式如下:
f(n) = true n =1, 2, 3
f(n) = !(f(n-1) && f(n-2) && f(n-3))
3. 根据数学归纳法分析:n = 1 f(n) =true; n = 2 f(n) =true; n = 3 f(n) =true; n = 4 f(n) =false; n = 5 f(n) =true; n = 6 f(n) =true; n = 7 f(n) =true; n = 8 f(n) =false; n = 9 f(n) =true; n = 10 f(n) =true; n = 11 f(n) =true; n = 12 f(n) =false;…
可以得出其实如果n不是4的整数倍,我就会赢。

题解代码:

(1) 递归法:

class Solution {
public:
    bool canWinNim(int n) {
        if ((n == 1) || (n == 2) || (n ==3)) {
            return true;
        }
        if (canWinNim(n - 1) && canWinNim(n - 2) && canWinNim(n - 3)) {
            return false;
        } else {
            return true;
        }
    }
};

这种解法可以解决问题,但是我提交LeetCode时显示超时,耗时比较大,一直想换成循环可能要快些,但是没有想出来代码怎么写。

(2)数学分析结论:

class Solution {
public:
    bool canWinNim(int n) {
        if (n % 4 != 0) {
            return true;
        } else {
            return false;
        }
    }
};

你可能感兴趣的:(leetcode,面试算法题,LeetCode题解,算法)