版本比较

标识

  • 该行被添加。
  • 该行被删除。
  • 格式已经改变。

原题链接:https://leetcode-cn.com/problems/elimination-game/

列表 arr 由在范围 [1, n] 中的所有整数组成,并按严格递增排序。请你对 arr 应用下述算法:

...

首先想到的是模拟,即按题目描述的步骤重复删除数字,直至剩下一个数字为止。实际操作时,由于数组元素只会出现1~n,所以只需要将待删除的数字置为0或一个负数即可,不必真正删除该数字。这种方式每次删除数字时需要遍历一轮数组,由于每次删除数组剩余元素的一半,所以一共需要删除 log2n 次,整体算法复杂度为O(nlogn)级别,考虑到n的数量级为109级别,算法极有可能超时。级别,考虑到n的数量级为10^9级别,算法极有可能超时。

实际操作时可以发现,从左到右删除数字时,最左边的数字必定会被删除,最右边的数字根据元素个数有两种情况:当元素个数是偶数时,这个数字不会被删除,当元素数个是奇数时,这个数字会被删除。同样,从右到左删除数字时,最右边的数字必定会被删除,而最左边的数字也和上面一样,只有当元素个数是偶数时才会被删除。实际操作时可以发现,从左到右删除数字时,最左边的数字必定会被删除,最右边的数字根据元素个数有两种情况:当元素个数是偶数时,这个数字不会被删除,当元素数个是奇数时,这个数字会被删除。同样,从右到左删除数字时,最右边的数字必定会被删除,而最左边的数字也和上面一样,只有当元素个数是奇数时才会被删除。

由此可以想到使用双指针法,使用左右两个指针指向每轮操作时最左和最右的元素,然后两个指针向中间移动,当指针相遇时返回相遇的数字。需要记录的变量有当前的删除方向,删除的步长,以及左右指针的位置,具体代码及注释如下:

...