算法总结之 环形单链表的约瑟夫问题

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

解读:

 输入:一个环型单向链表的头节点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异常,原因是,集合不可以一边遍历一边删除。

原文地址:https://www.cnblogs.com/toov5/p/7499535.html