力扣算法数学类—剑指 Offer 62. 圆圈中最后剩下的数字

目录

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

题目背景:

题解:

代码:

结果:


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

题目背景:

这是著名的约瑟夫环问题

这个问题是以弗拉维奥·约瑟夫命名的,他是1世纪的一名犹太历史学家。他在自己的日记中写道,他和他的40个战友被罗马军队包围在洞中。他们讨论是自杀还是被俘,最终决定自杀,并以抽签的方式决定谁杀掉谁。约瑟夫斯和另外一个人是最后两个留下的人。约瑟夫斯说服了那个人,他们将向罗马军队投降,不再自杀。约瑟夫斯把他的存活归因于运气或天意,他不知道是哪一个。

                                                         —— 【约瑟夫问题】维基百科

题解:

约瑟夫环问题的三种解法讲解 - 力扣(LeetCode)

将数据放在数组里,在数组后面加上了数组的复制,以体现是环状的

力扣算法数学类—剑指 Offer 62. 圆圈中最后剩下的数字_第1张图片

第一轮是 [0, 1, 2, 3, 4, 0, 1, 2, 3, 4] 。这一轮 2被 删除了。

第二轮是 [3, 4, 0, 1, 3, 4, 0, 1] 。这一轮 0 被删除了。

第三轮是 [1, 3, 4, 1, 3, 4] 。这一轮 4 被删除了。

第四轮是 [1, 3, 1, 3] 。这一轮 1 被删除了。

最后剩下3,下标是 0。

第四轮反推,补上 m 个位置,然后模上当时的数组大小 2
位置是(0 + 3) % 2 = 1。

第三轮反推,补上 m 个位置,然后模上当时的数组大小 3
位置是(1 + 3) % 3 = 1。

第二轮反推,补上 m 个位置,然后模上当时的数组大小 4
位置是(1 + 3) % 4 = 0。

第一轮反推,补上 m 个位置,然后模上当时的数组大小 5
位置是(0 + 3) % 5 = 3。

所以最终剩下的数字的下标就是3。因为数组是从0开始的,所以最终的答案就是3

总结一下反推的过程,就是 (当前index + m) % 上一轮剩余数字的个数

代码:

class Solution {
    public int lastRemaining(int n, int m) {
        int ans=0;
        //(index+m)%上一轮剩余数字的个数
        //倒着推得出结果前肯定还剩两个数,所以从i=2开始
        for(int i=2;i<=n;i++){
            ans=(ans+m)%i;
        }
        return ans;
    }
}

结果:

力扣算法数学类—剑指 Offer 62. 圆圈中最后剩下的数字_第2张图片

 

你可能感兴趣的:(题解,算法,leetcode,职场和发展)