面试题62:圆圈中最后剩下的数字(C++)

题目地址:https://leetcode-cn.com/problems/yuan-quan-zhong-zui-hou-sheng-xia-de-shu-zi-lcof/

题目描述

0,1,,n-1这n个数字排成一个圆圈,从数字0开始,每次从这个圆圈里删除第m个数字。求出这个圆圈里剩下的最后一个数字。

例如,0、1、2、3、4这5个数字组成一个圆圈,从数字0开始每次删除第3个数字,则删除的前4个数字依次是2、0、4、1,因此最后剩下的数字是3。

题目示例

示例 1:

输入: n = 5, m = 3
输出: 3

示例 2:

输入: n = 10, m = 17
输出: 2

解题思路

递归:此问题可以理解为约瑟夫问题,即n个人围成一圈,第一个人从1开始报数,报m的将被杀掉,下一个人接着从1开始报。如此反复,最后剩下一个,即为此轮胜利者,如此求最后的胜利者。使用递归的方式解决,递归公式如下,具体的推导流程可参考文末文章,思路很清晰。

迭代:此方法是在递归方法基础上进行修改,我们知道最终胜利的人是只有一个人的时候,此时她的下标index=0,继续分析,当有两个人的时候,胜利者的下标index=1,如此往复下去,可总结出迭代规律,具体见下面:

此处,我们取n=5,m=3。其中,f(n,m)为最终胜利者下标索引值。

0、1、2、3、4这5个数字组成一个圆圈,从数字0开始每次删除第3个数字,则删除的前4个数字依次是2、0、4、1,因此最后剩下的数字是3,即胜利者下标为3.

当人数n=1时,胜利者下标f(1,3)=0;

当人数n=2时,胜利者下标f(2,3)=(0+3)%2=1

当人数n=3时,胜利者下标f(3,3)=(1+3)%3=1

当人数n=4时,胜利者下标f(4,3)=(1+3)%4=0

当人数n=5时,胜利者下标f(5,3)=(0+3)%5=3

以此推广下去,可以总结得

n=1时,f(1,3)=0;

n=2时,f(2,3)=(f(1,3)+3)%3=1

n=3时,f(3,3)=((f(1,3)+3)%3+3)%3=1

n=4时,f(4,3)=(((f(1,3)+3)%3+3)%3+3)%4

n=5时,f(5,3)=((((f(1,3)+3)%3+3)%3+3)%4+3)%5

........

n=N时,f(N,M)=(f(N-1,M)%N;

程序源码

递归

class Solution {
public:
    int lastRemaining(int n, int m) {
        if(n == 1) return 0; //若剩下一个人,必然是胜利者
        else
        return (m + lastRemaining(n - 1, m)) % n;
    }
};

迭代

class Solution {
public:
    int lastRemaining(int n, int m) {
        int winIndex = 0;
        for(int i = 2; i <= n; i++)
        {
            winIndex = (winIndex + m) % i;
        }
        return winIndex;
    }
};

参考文章

https://leetcode-cn.com/problems/yuan-quan-zhong-zui-hou-sheng-xia-de-shu-zi-lcof/solution/huan-ge-jiao-du-ju-li-jie-jue-yue-se-fu-huan-by-as/

----------------------------------- 心之所向,素履所往;生如逆旅,一苇以航。 ------------------------------------------
原文地址:https://www.cnblogs.com/wzw0625/p/12672335.html