📘 題目敘述
你會得到一個整數陣列 nums。
有兩個玩家 Alice 和 Bob 輪流玩遊戲,Alice 先手。
每一回合,當前玩家可以選擇任意一段子陣列 nums[l..r],滿足 r - l + 1 < m,其中 m 是目前陣列長度。
被選的子陣列會被移除,剩下的元素會接起來形成新的陣列。
遊戲持續到陣列只剩下一個元素為止。
Alice 想讓最後剩下的元素最大,Bob 想讓最後剩下的元素最小。假設兩人都採取最佳策略,請回傳最後剩下的元素值。
子陣列是連續且非空的序列。
條件限制
1 <= nums.length <= 10^51 <= nums[i] <= 10^5
🧠 解題思路
這題看起來是博弈策略,但結果答案異常地簡單。
我一開始想很久:每回合可以刪掉一段長度 < m 的子陣列,等於「不能一次刪光」,那最佳策略到底是什麼?怎樣才能讓自己拿到最大?
後來我發現關鍵其實是:
如果讓對手還有機會動作,那最後剩下的數值就有可能被對手繼續往他想要的方向推(Alice 會被變小、Bob 會被變大)。
所以與其想很多複雜的刪法,不如把目標放在「讓對手不要有回合可以走」。
在陣列長度是 2 的時候,當前玩家可以刪掉長度 1 的子陣列(因為 1 < 2),直接讓陣列變成只剩一個元素,遊戲立刻結束,對手沒有機會再動。
因此 Alice 的核心目標就變成:
在她第一次行動後,把陣列變成長度 2,而且那兩個數字中「最後會留下的那個」要盡量大。
直覺上,最穩的做法就是保住邊界(因為刪中間、拼接後,最後留下的候選會落在拼接後的兩端),最後答案就會變成「兩端的較大者」。
老實說這個策略我也不太確定是不是最佳,只能先用 submit 來測試,結果居然 AC 了...
所有變數
nums:輸入陣列
🪜 主要流程步驟
直接回傳 max(nums[0], nums[nums.size() - 1])
真的傻爆眼的一行解 ==
💻 程式碼實作
class Solution {
public:
int finalElement(vector<int>& nums) {
return max(nums[0], nums[nums.size() - 1]);
}
};
🔗 題目連結
https://leetcode.com/contest/weekly-contest-487/problems/final-element-after-subarray-deletions/