剑指 Offer 62. 圆圈中最后剩下的数字
讲真的,现在的心情难以言表。
约瑟夫环一般是用循环链表做的,以前也写过。但是DP的做法太骚了。
1.表示状态f(n,m)=y表示:n个数,每次数m个,最后留下的数的下标为y。
2.状态转移方程
f(n,m)=(m+f(n-1,m))%n
怎么来的呢?
假设f(
n-1,m)=x,即
从index=0开始数,数x+1个数就是答案。
f(n,m)数一次m,划掉了下标为(m-1)%n
的数字。剩下n-1个数,变成了f(n-1,m),往后数x+1个数就是答案。
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
剑指 Offer 62. 圆圈中最后剩下的数字
class Solution { public int lastRemaining(int n, int m) { int x = 0; for(int i = 2; i <= n; i++) x = (x + m) % i; return x; } }