关键在于 index = (index + m - 1) % n这个公式的推导,注意这个 -1 噢~
classSolution{publicintlastRemaining(int n,int m){// 模拟链表法:LinkedList 会超时,用 ArrayListArrayList<Integer> list =newArrayList<>();for(int i =0; i < n; i++){list.add(i);}int index =0;while(n >1){// -1: 进行删除后前移index =(index + m -1)% n;list.remove(index);n--;}// 剩下最后一个~return list.get(0);}}
数学方法
倒推法,非常厉害,需要花时间理解。
甜姨的这篇题解写得很好
主要思路:经过 n 轮后,只剩下最后一个答案,此时下标一定为0。那么往前推到经过 n - 1轮后,此时有两个数字,如果能推出此时答案下标,那么就可以迭代地推到一开始(未去掉数字时)的答案下标,然后就得到答案了~
想推出上一轮下标,此时有什么信息:当前轮下标、当前轮数字个数、规定删除计数。
根据这三个已知量,有公式 ans = (m + ans) % i。其实就是往前补 m 个,然后再取余即可。
classSolution{publicintlastRemaining(int n,int m){// 数学方法:倒推// 最后剩下一个数字,下标就是0int ans =0;// 最后一轮剩下两个人,从后往前for(int i =2; i <= n; i++){// 推出“当前元素下标在上一轮中的下标”ans =(m + ans)% i;}// 结束后,元素下标 == 元素return ans;}}
二刷
模拟法
classSolution{publicintlastRemaining(int n,int m){List<Integer> loop =newArrayList<>();for(int i =0; i < n; i++){loop.add(i);}int index =0;while(loop.size()>1){index =(index + m -1)% loop.size();loop.remove(index);}return loop.get(0);}}
数学法:倒推, 先 + m 恢复到上一状态,再用上一状态长度 i 来进行数值修正
classSolution{publicintlastRemaining(int n,int m){int ans =0;for(int i =2; i <= n; i++){ans =(ans + m)% i;}return ans;}}
一 简介Spring Cloud Alibaba致力于提供微服务开发一站式解决方案。此项目包括开发分布式应用微服务的必需组件,方便开发者通过 Spring Cloud 编程模型轻松使用这些组件来开发分布式应用服务。依托 Spring Cloud Alibaba,你只需要添加一些注解和少量配置…
艺赛旗|做RPA生态先行者 RPA10.0全新首发免费下载 点击下载
引入会用到的库
from docx import Document
from docx.shared import Pt
from docx.enum.text import WD_PARAGRAPH_ALIGNMENT
from docx.shared import Cm
from docx.shared import RGBColor
表格样式
#方法一&#…