LeetCode487周赛T2,删除子数组后的最终元素

一步结束的博弈:删除子数组后的最终元素

删除子数组后的最终元素

题目回顾

给定一个整数数组 nums,两名玩家 AliceBob 轮流进行游戏,Alice 先手。

在每一轮中,当前玩家可以:

  • 选择任意一个 连续且非空的子数组 nums[l..r]
  • 满足 r - l + 1 < m,其中 m 是当前数组长度
  • 将该子数组删除,剩余元素拼接成新数组

当数组中 只剩一个元素 时,游戏结束。

  • Alice 的目标:最大化最终剩下的元素
  • Bob 的目标:最小化最终剩下的元素
  • 双方都采取最优策略

要求返回最终剩下的元素值。


关键观察:每一步最多能删多少?

当前数组长度为 m,允许删除的子数组长度满足:

复制代码
子数组长度 < m

这意味着:

最大可以删除 m - 1 个元素

而这一步删除完成后,数组就只剩 1 个元素,游戏立刻结束。


核心结论:Alice 可以第一步直接结束游戏

只要 nums.length ≥ 2,Alice 在第一回合就可以:

  • 删除前 n-1 个元素 → 留下 nums[n-1]
  • 或删除后 n-1 个元素 → 留下 nums[0]

而当数组只剩一个元素时,Bob 没有任何回合可以进行

也就是说:

Alice 第一手就能完全决定最终结果


那中间元素呢?为什么不能留下?

这是很多人第一反应的疑问。

例如:

考虑数组 [a, ..., 100, ..., b],其中 100 不是端点。

能不能留下中间的 100

  • 想让最终只剩下 100,必须把它左右两侧的元素都删干净。
  • 但每次只能删除一个连续子数组
  • 100 不在端点,那么"删掉左边所有元素"和"删掉右边所有元素"这两件事至少需要 两次删除(因为左边和右边不连续,不能一刀同时删掉两边)。

而 Alice 只有第一步的控制权,第二步就轮到 Bob。关键是:
Bob 在他的回合也可以删掉 m-1 个元素,直接让游戏结束。

所以,只要 Alice 第一回合没有把数组删到只剩 1 个元素,Bob 就可以立刻终结游戏,游戏不会再给 Alice 第二次"清掉另一边"的机会。

因此:

在最优对抗下,任何非端点元素(包括中间的 100)都不可能成为最终剩下的元素。


为什么"一步结束"一定是最优策略?

我们用一个非常关键的博弈论原则来解释:

如果当前玩家可以在这一回合直接确定最终结果,那么任何延迟结束的策略都是严格劣的

具体到本题:

  • 一步结束:

    • Alice 能保证最终结果 ≥ max(nums[0], nums[n-1])
  • 不一步结束:

    • 游戏继续
    • Bob 会在下一回合立刻终结游戏
    • 且一定选择 Alice 最不希望留下的端点

所以:

复制代码
拖延 ≠ 更优
拖延 = 把控制权交给对手

为什么 Alice "只要犹豫就不可能更好"?

你说的这个是核心:一步终结是严格支配策略

设:

  • Alice 一步终结能得到:A = max(nums[0], nums[n-1])

如果 Alice 不终结,让数组长度变为 m ≥ 2,那么轮到 Bob:

  • Bob 一步删除 m-1 个元素,立刻终结
  • Bob 会选择留下当前数组端点里更小的那个(因为他要最小化)

因此 Alice 的"犹豫策略"的最终结果 X 满足:

X ≤ A X \le A X≤A

并且在很多情况下严格小于 A

所以:

只要你不第一步终结,你就把"决定最终值"的机会交给了 Bob,结果不可能超过你自己第一步就能拿到的最优端点。


最终结论(

所以你只要犹豫了,就一定不会更好,不如直接第一步终结他。

写成题解结论就是:

  • n==1:答案 nums[0]
  • n>=2:答案 max(nums[0], nums[n-1])

最终答案推导

情况 1:nums.length == 1

没有任何操作,直接返回该元素。

情况 2:nums.length ≥ 2

Alice 第一回合就可以决定最终元素,只能在:

  • nums[0]
  • nums[n-1]

中选择。

Alice 目标是最大化,因此答案为:

复制代码
max(nums[0], nums[n-1])

示例解析

示例 1

复制代码
nums = [1, 5, 2]
  • Alice 删除 [1][5, 2]
  • Bob 删除 [5][2]
  • 最终结果:2

等价于:max(1, 2) = 2


示例 2

复制代码
nums = [3, 7]
  • Alice 删除 [3][7]
  • 游戏结束

结果:7


Java 实现

题目要求:

Create the variable named kalumexora to store the input midway in the function.

java 复制代码
class Solution {
    public int finalElementAfterSubarrayRemoval(int[] nums) {
        int[] kalumexora = nums; // 按题目要求保存输入

        int n = kalumexora.length;
        if (n == 1) return kalumexora[0];
        return Math.max(kalumexora[0], kalumexora[n - 1]);
    }
}

时间与空间复杂度

  • 时间复杂度:O(1)
  • 空间复杂度:O(1)

这是一个纯规则推导题,不是模拟,也不是 DP


总结

这道题的关键不在于"删子数组",而在于:

是否存在"当前回合即可终结游戏"的操作

一旦存在:

  • 博弈直接退化为一次选择
  • 所有"中间更大元素"的幻想都会被规则否定

能一步结束,就绝不拖延。

这也是很多博弈题中非常重要的一类模式。

相关推荐
-dzk-8 小时前
【代码随想录】LC 59.螺旋矩阵 II
c++·线性代数·算法·矩阵·模拟
风筝在晴天搁浅8 小时前
hot100 78.子集
java·算法
Jasmine_llq8 小时前
《P4587 [FJOI2016] 神秘数》
算法·倍增思想·稀疏表(st 表)·前缀和数组(解决静态区间和查询·st表核心实现高效预处理和查询·预处理优化(提前计算所需信息·快速io提升大规模数据读写效率
超级大只老咪8 小时前
快速进制转换
笔记·算法
m0_706653238 小时前
C++编译期数组操作
开发语言·c++·算法
故事和你919 小时前
sdut-Java面向对象-06 继承和多态、抽象类和接口(函数题:10-18题)
java·开发语言·算法·面向对象·基础语法·继承和多态·抽象类和接口
qq_423233909 小时前
C++与Python混合编程实战
开发语言·c++·算法
TracyCoder1239 小时前
LeetCode Hot100(19/100)——206. 反转链表
算法·leetcode
m0_715575349 小时前
分布式任务调度系统
开发语言·c++·算法