约瑟夫环

题目

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

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

解法:

class Solution {
    public int lastRemaining(int n, int m) {
        int f = 0;
        for (int i = 2; i != n + 1; ++i) {
            f = (m + f) % i;
        }
        return f;
    }
}

我们有n个数,下标从0到n-1,然后从index=0开始数,每次数m个数,最后看能剩下谁。我们假设剩下的数的下标为y(不一定是最后剩下的,这里泛指每一步之后剩下的),则我们表示为

f(n,m) = y

注意,y是下标,即从0开始数的第y+1个数

然后我们假设f(n-1,m)=x,然后来找一找f(n,m)f(n-1,m)是什么关系。

于是我们来思考f(n,m)时考虑以下两件事:

  1. 有n个数的时候,要划掉一个数,然后就剩n-1个数了呗,那划掉的这个数,下标是多少?
  2. 划完了这个数,往后数,数x+1个数,停在谁身上谁就是我们的答案。当然了,数的过程中你得取余

问题一:有n个数的时候,划掉了谁?下标是多少?

因为要从0数m个数,那最后肯定落到了下标为m-1的数身上了,但这个下标可能超过我们有的最大下标(n-1)了,所以要模n。

所以有n个数的时候,我们划掉了下标为(m-1)%n的数字。

问题二:我们划完了这个数,往后数x+1下,能落到谁身上呢,它的下标是几?

划完了这个数,下一个数变成了开头,你往后数x+1,它下标就是(m-1)%n +x+1,取模,所以答案为[(m-1)%n+x+1]%n,则

f(n,m)=[(m-1)%n+x+1]%n

其中x=f(n-1,m)

f(n,m)=[(m-1)%n+x+1]%n
      =[(m-1)%n%n+(x+1)%n]%n
      =[(m-1)%n+(x+1)%n]%n
      =(m-1+x+1)%n
      =(m+x)%n

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值