剑指 Offer 62. 圆圈中最后剩下的数字 (约瑟夫环)

LeetCode - 剑指 Offer 62. 圆圈中最后剩下的数字


参考题解 by leetcode- Vancomycin

题目描述

难度:简单

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

解题分析

定义状态 dp(n,m) 为长度为n的序列 (0 - n-1)不断删除第m个元素最后剩下的元素下标;

假设 n = 5 m = 3,此时有所求序列 0 1 2 3 4, 当尝试进行第一轮删除之后;
此时序列长度变为 n - 1,状态更新为 dp(n-1,m),序列为 3 4 0 1;
即元素2也就是第m个元素被删除(下标为m-1),而下一轮的开头变成了 3 ,即下标为m的元素;

以上是dp(5,3)经过第一轮删除后变为dp(n-1,m)之后的序列状态,为了区分正常状态,该状态暂定为 dp’(n-1,m);

当 n = 4, m = 3 时,状态为dp(n-1,m),序列为 0 1 2 3;
此时有dp’(n-1,m)对应序列 3 4 0 1 , dp(n-1,m)对应序列 0 1 2 3,两者对应表格如下:

dp(n-1,m)01n-m-1n-mn-3n-2
dp’(n-1,m)mm+1n-10m-3m-2

可见对应关系有 dp’(n-1,m) = ( dp(n-1,m) + m) % n;

由于 dp(n,m) == dp’(n-1,m),即二者最终结果是一致的。
所以有状态转移方程 dp(n,m) = ( dp(n-1,m) + m) % n,需要注意的是,n为当前序列长度。
当n = 1时,序列所剩元素下标为0。

code

	public int lastRemaining(int n, int m){
        int ans = 0; // dp(1,m)
        for(int i = 2; i <= n; ++i) ans=(ans+m)%i; // dp(i,m) = (dp(i-1,m)+m)%i
        return ans;
    }

总结

这题困扰了我好久,lc有很多题解我都没有看懂,只能说我能力太差了。。。
幸好看到了一篇我能看懂的题解(救大命)特此结合自己的想法记录一下该题解。



岁月悠悠,衰微只及肌肤;热忱抛却,颓废必致灵魂

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值