圆圈中最后剩下的数字

题目:0, 1, … , n-1 这 n 个数字排成一个圈圈,从数字 0 开始每次从圆圏里删除第 m 个数字。求出这个圈圈里剩下的最后一个数字。

解法一

这里用LinkedList的性能比ArrayList的性能好,因为我们不断的要删除List中的某个元素。如果用ArrayList里面有大量的System.arraycopy。

public static void main(String[] args) {
    System.out.print("list中原来的数字为: " + lastRemaining(10, 3));
}

public static int lastRemaining(int n, int m) {
    LinkedList list = new LinkedList();
    for (int i = 0; i < n; i++) {
        list.addLast(i);
    }
    System.out.print("list中原来的数字为: ");
    for (Integer inte : list) {
        System.out.print(inte + ",");
    }
    System.out.println();

    int index = 0;// list中元素的指针,list中的元素是从0开始计数的

    while (list.size() > 1) {
        for (int i = 1; i < m; i++) {// 让index增加m-1,
            // index的值大于等于list中元素个数时,让index指向list的第一个元素,模拟循环链表
            if (index >= (list.size() - 1)) {
                index = 0;
            } else {
                index++;
            }
        }

        list.remove(index);// 删除list中index处的元素

        System.out.println("删除index为" + index + "的元素后剩下的元素是:");

        for (Integer inte : list) {
            System.out.print(inte + ",");
        }
        System.out.println();
    }
    return list.get(0);
}

结果:

list中原来的数字为: 0,1,2,3,4,5,6,7,8,9,
删除index为2的元素后剩下的元素是:
0,1,3,4,5,6,7,8,9,
删除index为4的元素后剩下的元素是:
0,1,3,4,6,7,8,9,
删除index为6的元素后剩下的元素是:
0,1,3,4,6,7,9,
删除index为1的元素后剩下的元素是:
0,3,4,6,7,9,
删除index为3的元素后剩下的元素是:
0,3,4,7,9,
删除index为0的元素后剩下的元素是:
3,4,7,9,
删除index为2的元素后剩下的元素是:
3,4,9,
删除index为1的元素后剩下的元素是:
3,9,
删除index为1的元素后剩下的元素是:
3,
list中原来的数字为: 3

解法二:

建造一个boolean数组,大小为总共数字的个数和,默认boolean数组的每个元素都是false,数到谁的时候,将数组对对应index的值改为true。知道最后只剩下一个元素值为false,得到此index。

private final static int COUNT_N = 10;
private final static int COUNT_M = 3; //

public static void main(String[] args) {
    boolean[] bs = new boolean[COUNT_N];
    /**
     * count 的初始值是0,取值是1-COUNT_M。
     */
    int removeCount = 0, count = 0, index = -1, arrIndex = -1;

    System.out.println("起始:");
    printLog(bs);
    System.out.println("-----------------");

    while (removeCount < bs.length - 1) {
        arrIndex++;
        if (arrIndex >= bs.length) {
            arrIndex = 0;
        }

        if (!bs[arrIndex]) {
            count++;
        }

        if (count >= COUNT_M) {
            bs[arrIndex] = true;
            printLog(bs);
            count = 0;
            removeCount++;
        }
    }
    
    for (int i = 0; i < bs.length; i++) {
        if (!bs[i]) {
            index = i;
            //打印最后一个数字的索引
            System.out.println(index);
            break;
        }
    }
}

private static void printLog(boolean[] bs) {
    for (boolean b : bs) {
        System.out.print(b + "\t");
    }
    System.out.println();
}
圆圈中最后剩下的数字_第1张图片
Paste_Image.png

你可能感兴趣的:(圆圈中最后剩下的数字)