【剑指 Offer 62. 圆圈中最后剩下的数字】

【剑指 Offer 62. 圆圈中最后剩下的数字】

题目描述:

来源:力扣(LeetCode)
链接: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

  • 提示
    1 <= n <= 10^5
	1 <= m <= 10^6

解析思路1:

  • 参考k神解析.
  • “约瑟夫环” 问题,学习使用 动态规划 解决。
  • 即是后一步的结果需要使用前一步的数值。
  • 在这里插入图片描述
  • 对于「n,m 问题」,首轮删除环中第 m 个数字后,得到一个长度为 n−1 的数字环。由于有可能m>n ,因此删除的数字为 (m−1)%n ,删除后的数字环从下个数字(即 m%n )开始,设t=m%n ,可得数字环:

在这里插入图片描述
- 在这里插入图片描述

  • f(n) 可由 f(n - 1)得到,f(n−1) 可由 f(n−2) 得到,……,f(2) 可由 f(1) 得到;因此,若给定 f(1) 的值,就可以递推至任意 f(n) 。而「1, m 问题」的解 f(1) = 0 ,即无论 m 为何值,长度为 1 的数字环留下的结果一定是数字 0 。

在这里插入图片描述

  • 算法流程示意图
  • 动态规划算法:
  • 设定初始的状态参数 + 推得状态转移方程
  • 1、设定 【i,m】的变量值为 res[i]、【1,m】的值恒为 0 ;
  • 2、状态转移方程: res[ i ] 的结果由 res[ i-1 ] 递推得到:
  •  			 res[ i ]  =  ( res[ i-1 ]   + m)  %  n
    
  • 3、返回值 :【n,m】问题的变量值 res[n];
    在这里插入图片描述

代码(python3)


class Solution:
    def lastRemaining(self, n: int, m: int) -> int:
        res = 0;
        for num in range(2,n+1):
            res = (res + m ) % num;
        return  res;

代码(cpp)


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

复杂度分析:

  • 时间复杂度 O(n):状态转移循环n−1 次使用 O(n) 时间,状态转移方程计算使用 O(1) 时间;
  • 空间复杂度 O(1) : 使用常数大小的额外空间
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值