IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> Java解决约瑟夫环问题(通俗易懂版) -> 正文阅读

[Java知识库]Java解决约瑟夫环问题(通俗易懂版)

约瑟夫环问题
?????????约瑟夫环(约瑟夫问题)是一个数学的应用问题:已知n个人(以编号1,2,3…n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。通常解决这类问题时我们把编号从0~n-1,最后 结果+1即为原问题的解。
解法一:利用链表
?????????我们可以把每一个人变成一个链表,然后不断地循环这个链表。每次删除一个结点,直到最终只剩下一个结点的时候就表示我们找到个!

	//设计一个结点类
	class Node{
        int val;
        Node next;
        public Node(int val){
            this.val = val;
        }
    }
    /**
     * 循环链表
     * @param n 一共有n个人(每个人的编号从0开始到-1)
     * @param m 每次出去第m个人(每次报数也是从0开始到m-1)
     * @return
     */
    public int LastRemaining_Solution3(int n, int m) {
    	//这里表示没有人的情况
        if(n == 0 || m == 0){
            return -1;
        }
        //创建一个头结点(将第一个人设置为头)
        Node head = new Node(0);
        //把头结点保存一妇女进行循环~
        Node temp = head;
        //然后我们从第二个人开始,不穿创建结点并和之前的节点进行连接
        for(int i = 1 ; i < n ; i++){
            temp.next = new Node(i);
            temp = temp.next;
        }
        //让最后一个人和我们的第一个人也连在一起,这样就可以循环起来了~
        temp.next = head;
        //因为我们设计的是从0开始
        int index = 0;
        //当链表不止一个结点的时候才需要循环了
        while(head.next != head){
        	//这里还是我们停在需要删除的节点的前一个
            if(index == m-2){
            	//删除该节点
                head.next = head.next.next;
                //同时我们的报数需要清0,重新开始报数
                index = 0;
            }
            //如果不是要删除的节点那就正常报数
            else{
                index++;
            }
            //每次向后移动一个
            head = head.next;
        }
        //最终返回剩下的那一个节点的值就好啦~
        return head.val;
    }

解法二:迭代
?????????我们先举个例子~假设一共有5个人(n = 5),然后从0开始编号,从0开始报数,报到第2个出列(m = 3),我们来模拟一下这个过程。

0 1 2 3 4 (第一次出队的是2)
3 4 0 1 (第二次出队的是0)
1 3 4 (第三次出队的是4)
1 3 [ 1 3 ](第四次出队的是1)
3(最终剩余的是3)

?????????我们做这个题的时候只知道最后剩下的一定是一个数,他的下标是0,那我们可以从下往上看,根据下标找到最终的那个数。
?????????所以我们需要看怎么从下面这一层的下标找到这个数在上一层的下标,我们发现当前下标加上m就是我们再上一层的下标,但是这个不一定是真实的下标,因为有可能我们当前的人数是小于m的,所以得到的下标就是一个将人数复制了之后的下标,那么想要得到真实的下标就是进行一个%操作就好,我们知道每次只出队1 个人,那么从后往前的人数分别是0,1,2…所以我们%一下这个人数就得到了真实的下标,然后再一样的办法,得到上一次循环该数的下标,直到到了最开始就知道我们这个最终剩下的人的下标,因为我们最开始的编号是从0开始的,所以回到最初的时候,下标就是编号,直接返回就好了!
在这里插入图片描述
?????????我们看这个图,红色的是每次要删除的数据,蓝色的是我们的到的下标,绿色的是真实的下标。我们最开始只知道最后一个3的下标是0,然后不断往上一层找,拿到3的下标。
代码

	public int LastRemaining_Solution(int n, int m) {
		//先判断没有人的状况
        if(n == 0 || m == 0){
            return -1;
        }
        //我们知道最后的下标是0
        int index = 0;
        //从下往上找最初的下标
        for(int i = 2 ; i <= n ; i++){
        	//当前下标加上m是蓝色的那个下标
        	//再模一下当前的人数就是真实的下标~
            index = (index + m) % i;
        }
        //最终直接返回下标~
        return index;
    }

还有的时候我们的是从1开始编号报数的,那么具体的代码是

public int LastRemaining_Solution2(int n, int m) {
        if(n == 0 || m == 0){
            return -1;
        }
        int index = 1;
        for(int i = 2 ; i <= n ; i++){
            index = (index + m) % i;
            if(index == 0){
                index += i;
            }
        }
        return index;
    }

?????????会比0开始的多一个步骤,但是思路完全一样~

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-06-14 22:21:09  更:2022-06-14 22:26:09 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 18:36:40-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码