zoukankan      html  css  js  c++  java
  • 算法总结之 环形单链表的约瑟夫问题

    著名的约瑟夫杀人问题 哈哈哈哈

    解读:

     输入:一个环型单向链表的头节点head和报数m

    返回: 最后生存下来的节点,并且这个节点自己组成环形单向链表,其他的节点都删掉

    进阶问题: 如果链表节点数为N,想在时间复杂度为O(N)时完成原问题的要求,咋办?

    普通解法: 

      如果链表为空或者节点数为1  或者m<1  直接返回

      在环形链表中遍历每个节点,不断转圈,不断报数

      当报数到m时,就删除当前报数的节点

      删除节点后把剩下的继续连城环状 继续转圈报数 继续删除

     不停删除 直到唤醒链表中只剩下一个节点 介绍~

    看代码:

    package TT;
    
    public class Test91 {
    
        public class Node{
            public int value;
            public Node next;
            public Node(int data){
                this.value = data;
            }
        }
        
        public Node josephusKill(Node head, int m){
            
            if(head==null || head.next==null || m<1){
                return head;
            }
            Node last=head;
            while(last.next != head){
                last=last.next;
            }
            int count=0;
            while(head != last){
                if(++count==m){
                    last.next=head.next;
                    count=0;
                }else {
                    last=last.next;
                }
                head = last.next;
            }
            return head;
        }
        
        
        
        
        
    }

    用集合方案解决:

    package com.toov5.test;
    
    
    import java.util.ArrayList;
    import java.util.List;
    
    public class Test9 {
         
        public static Integer getLastOne(List<Integer> list,int m) {
            
            int count  =  1;
            int index = 0;
            while(list.size() !=1) {
                if (count % m == 0) {
                    list.remove(index);
                    System.out.println(list);
                  //结合自己画的图,看看此时指针指向的元素是谁哈
                  //System.out.println(list.get(index));
                }
                if ( index<list.size()-1) {
                    index++;
                }else {
                    index=0;
                }
                count++;    
            }        
            return list.get(0);        
        } 
        
        public static void main(String[] args) {
            List<Integer> list =new ArrayList<>();
             list.add(1);
             list.add(2);
             list.add(3);
             list.add(4);
             list.add(5);
             
             System.out.println(getLastOne(list, 3));
        }
        
    }

     注意 list 做for 循环时候

    不可以进行操作 调用其api之类的!

    ConcurrenModificationException异常,原因是,集合不可以一边遍历一边删除。

  • 相关阅读:
    算法初步——贪心
    sql去除重复记录 且保留id最小的 没用
    项目二:品优购 第三天
    Restful
    lucene 第一天
    lucene和solr
    zookeeper 面试题 有用
    dubbo 相关面试题 有用
    webservice CXF 相关面试题
    POI技术
  • 原文地址:https://www.cnblogs.com/toov5/p/7499535.html
Copyright © 2011-2022 走看看