62.圆圈中最后剩下的数字(简单)

考点:本题考查抽象建模能力

题目描述:

0,1,,n-1这n个数字排成一个圆圈,从数字0开始,每次从这个圆圈里删除第m个数字。求出这个圆圈里剩下的最后一个数字。
例如,0、1、2、3、4这5个数字组成一个圆圈,从数字0开始每次删除第3个数字,则删除的前4个数字依次是2、0、4、1,因此最后剩下的数字是3。
(1) 0 1 2 3 4 删除2
(2) 3 4 0 1 删除0
(3) 1 3 4 删除4
(4) 1 3 删除1
(5) 3 最后剩下3
这是著名的约瑟夫环问题

思路一:用环形链表模拟圆圈

创建一个共有n个节点的环形链表,然后每次在这个链表中删除第m个节点
使用一个list来模拟,并使用一个索引current指向删除的位置,当current的值为list的size,就让current回到头位置

import java.util.LinkedList;
import java.util.List;
public class Solution {
    public int LastRemaining_Solution(int n, int m) {
        if(n<1||m<1)
            return -1;
        List<Integer> list=new LinkedList<>();
        for(int i=0;i<n;i++){
            list.add(i);
        }
        int current = -1;
        while(list.size()>1){
            for(int i=0;i<m;i++){
                current++;
                if(current==list.size())
                    current = 0;
            }
            list.remove(current);
            current--;
        }
        return list.get(0);
    }
}

上述代码中存在重复的遍历,每删除一个数字需要m步运算,共有n个数字,总的时间复杂度为O(mn)

思路二:分析每次被删数字的规律

f(n,m)表示每次在n个数字0,1,...,n-1中删除第m个数字最后剩下的数字
当n=1时,f(n,m)=0
当n>1时,f(n,m)=[f(n-1,m)]%n

import java.util.LinkedList;
import java.util.List;
public class Solution {
    public int LastRemaining_Solution(int n, int m) {
        if(n<1||m<1)
            return -1;
        int res = 0;
        for(int i=2;i<=n;i++){
            res = (res+m)%i;
        }
        return res;
    }
}

时间复杂度为O(n)

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 在C语言中,五种基本数据类型存储空间长度的排列顺序是: A)char B)char=int<=float C)ch...
    夏天再来阅读 3,421评论 0 2
  • 1、题目描述 0,1,...,n-1这n个数字排成一个圆圈,从数字0开始每次从这个圆圈里删除第m个数字,求出这个圆...
    鉴闻俗说阅读 541评论 0 0
  • 女主的名字:苏夏 女主的仇家(花花公子):林煊 仇家的妹妹:林歆 女主的男闺蜜(大发明家):万瑞熊 女主的男闺蜜(...
    亡魂师阅读 627评论 0 0
  • 这是2014年最后的怀旧,我在此怀念我小时候的书店。 那是二零零几年,我上小学三四年级,懂了许多的字,便开始了我的...
    苍蓝公子阅读 236评论 0 2
  • 我们信主受洗归于基督是不是我们所有的罪都被赦免了?以后我们如果犯罪的话是不是就不会受到审判了呢?答案:当然不是,我...
    sunlin1234阅读 1,023评论 0 0