java面试题之约瑟夫环问题求解策略《四》

2018-08-30  本文已影响0人  铭戈栈
import java.util.ArrayList;

/**
 * 约瑟夫环 问题
 * 获取幸运数字
 * 思路:
 * ①集合数组的
 * ②递归
 */
public class josephRing03 {
    public static void main(String[] args){
        System.out.println("第一种方法:集合法");
        System.out.println(getLuckNum01(10));
        System.out.println("第二种方法:递归法");
        System.out.println(getLuckNum02(10,3,8));
        System.out.println(getLuckNum02(9,3,7));
        System.out.println(getLuckNum02(8,3,6));
        System.out.println(getLuckNum02(7,3,5));
        System.out.println(getLuckNum02(6,3,4));
        System.out.println(getLuckNum02(5,3,3));
        System.out.println(getLuckNum02(4,3,2));
        System.out.println("第三种方法:公式法");//本质也是递归
        System.out.println(getlive(10, 3));
        System.out.println(getlive( 9, 3));
        System.out.println(getlive( 8 , 3));
        System.out.println("第三.001种方法:公式形象记忆法");//本质也是递归
        System.out.println(getLuckNum(10, 3));
        System.out.println(getLuckNum(9, 3));
        System.out.println(getLuckNum(8, 3));


    }

    //①数组集合法
    public static int getLuckNum01(int num) {
        //1.定义一个集合,并且添加人进去,10环就add十个人进去,100人环就add100个人进去
        ArrayList<Integer> list = new ArrayList<>();
        for (int i = 1; i <= num; i++) {
            list.add(i);
        }
        //2.定义一个指针,区别于下面的i,这个count是直接跟人头对接的,所以要从1开始。
        int count = 1;
        //3.遍历所有元素,一直“杀死”人直到只剩下最后一个人即list.size()!=1时都要继续遍历
       /* System.out.println(list.size());*/
        for (int i=0;list.size()!=1;i++){
            //4.如果已经遍历到最后一个人了,则重新开始,i重新等于0,又一个新环来进行“杀人”游戏
            //注:这里要设置判断条件为list.size(),而不是list.size()-1是有原因的
            //因为i作为下标一直遍历增加,直到最后一个下标,都是可以杀人的,也就是说还可以进行下面的if判断以及count++
            //所以,直到i增加到list.size时,已经可以说是下标越界了,此时就要使得要越界的这个i变成0,重新开始新的“i生”(人生~哈哈哈)
            if(i==list.size()){
                i =0;
            }
            //5.当指针的对3求余为0时,去除掉list的这个元素。
            //注:由于少了一个数,后面的数会补上前来,下标不变的话,i又必须得-1,才能不会错过当前的人
             if(count%3 == 0){
                list.remove(i--);
            }
            //6.count继续累加
            count++;
        }
        return list.get(0);

    }
    //②递归法(大神法)
    public static int getLuckNum02(int sum,int value,int n) {
        if( n ==1){
            return (sum+value-1)%sum;
        }
        else{
            return (getLuckNum02(sum-1, value, n-1)+value)%sum;
        }
    }
    //3.公式法
    public static int getlive(int n,int m){
        if(n == 1){return 1;}
        return (getlive(n-1,m)+m-1)%n+1;//背下来就可以了
    }
    //3.01形象记忆公式法
    public static int getLuckNum(int sumMan,int jiange){
        if(sumMan == 1) {
            return 1;
        }
        else{
            return (getLuckNum(sumMan-1,jiange)+jiange-1)%sumMan+1;//背下来就可以了
        }

    }



}

总结:
①直接背公式。
②理解指针指向。

欢迎访问个人搭建的博客:ympeng.top

上一篇下一篇

猜你喜欢

热点阅读