leetcode 292 NimGame

1. Problem description

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.

You and your friends, two people play Nim games together:

There is a pile of stones on the table.
You take turns in your own rounds, and you are the first mover.
In each round, the person in his turn removes 1-3 stones.
The person who removes the last stone is the winner.
Assume that every step of yours is the optimal solution. Please write a function to determine whether you can win the game given the number of stones n. If you can win, return true; otherwise, return false.

Note that the number of piles of stones is an even number, so the piles you two take must be the same.
The total number of stones is an odd number, which means that you cannot have the same number of stones in the end, and there must be a winner or loser.

2. Solution 1

This problem looks a bit like a Fibonacci sequence problem. Let's first use the idea of ​​Fibonacci sequence to solve it.

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

The above code can complete the corresponding function. But obviously, the efficiency is very low, because there will be a problem of recursive calling methods. When n becomes larger, the complexity will be very high.

3. Solution 2

When encountering this kind of complicated problem, one way we often use is the reverse method.
If you want to win the final round, the remaining stones need to be 1, 2, or 3, so you can get it all at once.
Then, when the opponent takes the last time, if there are 4 stones left, no matter if he takes 1, 2, or 3, the remaining stones must be 1-3.
So how do you make the opponent have 4 stones left when they take it for the last time? If we can make our own choice when there are 5, 6, or 7 stones left, then we can ensure that when the opponent takes it, there are 4 stones left.

Therefore, if you continue to derive it, you will find that as long as it is a multiple of 4 when the stone is taken, it will definitely lose.

So the final solution is very simple

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

As long as n% 4 != 0, then the first mover will win.

Guess you like

Origin blog.csdn.net/bitcarmanlee/article/details/114022435