这是我参与2022首次更文挑战的第2天,活动详情查看:2022首次更文挑战
题目
列表 arr 由在范围 [1, n] 中的所有整数组成,并按严格递增排序。请你对 arr 应用下述算法:
- 从左到右,删除第一个数字,然后每隔一个数字删除一个,直到到达列表末尾。
- 重复上面的步骤,但这次是从右到左。也就是,删除最右侧的数字,然后剩下的数字每隔一个删除一个。
- 不断重复这两步,从左到右和从右到左交替进行,直到只剩下一个数字。
给你整数
n,返回arr最后剩下的数字。
示例
输入:n = 9
输出:6
解释:
arr = [1, 2, 3, 4, 5, 6, 7, 8, 9]
arr = [2, 4, 6, 8]
arr = [2, 6]
arr = [6]
输入: n = 1
输出: 1
提示
1 <= n <= 10
解题思路
该题最直观的解题方法,就是使用一个指针(result)来进行模拟操作,在每次排除掉一半的元素之后,指针根据步长(step),移动至下一存活元素的位置, 当只剩下一个元素时,返回最终结果。
代码实现
class Solution {
public static int lastRemaining(int n) {
// 结果
int result = 1;
// 步长
int step = 1;
// 转向
boolean direction = true;
// 当元素数量大于1时,需要排除掉一半的元素
while (n > 1) {
if (direction) {
// 正向,指针根据步长移动至下一元素处
result = result + step;
} else {
// 反向,判断剩余数量是否为偶数
// 偶数则指针不需要移动
// 奇数则指针需要移动至下一存活元素处
result = (n % 2 == 0) ? result : result + step;
}
// 转向
direction = !direction;
// 每次排除一半元素
n = n >> 1;
// 跳过排除掉的元素间隔
step = step << 1;
}
// 返回结果
return result;
}
}
另外在力扣的题解区中,【宫水三叶】大佬使用约瑟夫环的思路来进行解题,一行代码搞定,对于最求最少代码量的小伙伴一定不能错过!
class Solution {
public int lastRemaining(int n) {
return n == 1 ? 1 : 2 * (n / 2 + 1 - lastRemaining(n / 2));
}
}
【宫水三叶】大佬题解原文地址:leetcode-cn.com/problems/el…
最后
寻找小伙伴一起打卡学习,2022一起加油!!!