解法1:数学 + 迭代+递归

反推过程:(当前index + m) % 上一轮剩余数字的个数
最终剩下一个人时的安全位置肯定为1,反推安全位置在人数为n时的编号
人数为1: 0
人数为2: (0+m) % 2
人数为3: ((0+m) % 2 + m) % 3
人数为4: (((0+m) % 2 + m) % 3 + m) % 4
........
迭代推理到n就可以得出答案

    public int LastRemaining2(int n, int m){
        if (m < 1 || n < 1)
            return -1;
        int last = 0;
            //最终剩下一个人时的安全位置肯定为1,反推安全位置在人数为n时的编号
        // i代表有目前有个人 
           //最后一轮剩下2个人,所以从2开始反推
        for (int i = 2; i <= n; i++)
            last = (last + m) % i;
        return last;
    }

解法2:链表

将[0,n-1]依次存储在链表中
只要链表的长度不为1,就一直循环,如果到了第m个就remove;否则将其添加到链表尾部
时间复杂度为O(nm)

public int LastRemaining(int n, int m){
        LinkedList<Integer> list=new LinkedList<>();
        if(m<1 || n<1){
            return -1;
        }
        for(int i=0;i<n;i++){
            list.add(i);
        }
        int bt=0;
        while(list.size()>1){
            bt=(bt+m-1)%list.size();
            list.remove(bt);
        }
        return list.get(0);
    }