文章目录
- Tag
- 题目来源
- 解题思路
- 方法一:贪心+排序
- 写在最后
Tag
【贪心+排序】【数组】【2024-02-02】
题目来源
1686. 石子游戏 VI
解题思路
方法一:贪心+排序
思路
假设有两个石子 i
和 j
,Alice 和 Bob 认为它们的价值分别为 a i a_i ai, b i b_i bi 和 a j a_j aj, b j b_j bj,即 a l i c e V a l u e s = [ a i , a j ] aliceValues = [a_i, a_j] aliceValues=[ai,aj], b o b V a l u e s = [ b i , b j ] bobValues = [b_i, b_j] bobValues=[bi,bj]。
如果 Alice 取了石子 i
,Bob 取了石子 j
,则它们的分差为 a i − b j a_i - b_j ai−bj;如果 Alice 取了石子 j
,Bob 取了石子 i
,则它们的分差为 a j − b i a_j - b_i aj−bi。对于 Alice,这两个方案选择哪一种取决于这两个的分差: ( a i − b j ) − ( a j − b i ) = ( a i + b i ) − ( a j + b j ) (a_i - b_j) - (a_j - b_i) = (a_i + b_i) - (a_j + b_j) (ai−bj)−(aj−bi)=(ai+bi)−(aj+bj)。当这个值大于 0,Alice 会优先选择石子 i
,当这个值小于 0 时,Alice 会优先选择 j
。因此,Alice 在选择时,会优先选择 ( a i + b i ) (a_i + b_i) (ai+bi) 大的石子。
实现中,我们只需要将这两个数组 aliceValues
和 bobValues
对应元素相加后降序排序,然后 Alice 和 Bob 依次选取,然后计算两人的分数后进行比较返回结果。
算法
class Solution {
public:int stoneGameVI(vector<int>& aliceValues, vector<int>& bobValues) {int n = aliceValues.size();vector<tuple<int, int, int>> values;for (int i = 0; i < n; ++i) {values.emplace_back(aliceValues[i] + bobValues[i], aliceValues[i], bobValues[i]);}sort(values.begin(), values.end(), [](tuple<int, int, int>&a, tuple<int, int, int>&b) {return get<0>(a) > get<0>(b);});int aliceSum = 0, bobSum = 0;for (int i = 0; i < n; ++i) {if (i & 1) {bobSum += get<2>(values[i]);}else {aliceSum += get<1>(values[i]);}}if (aliceSum > bobSum) {return 1;}else if (aliceSum == bobSum) {return 0;}else {return -1;}}
};
复杂度分析
时间复杂度: O ( n l o g n ) O(nlogn) O(nlogn), n n n 为数组的长度。
空间复杂度: O ( n ) O(n) O(n),为额外的数组 values
的大小。
写在最后
如果您发现文章有任何错误或者对文章有任何疑问,欢迎私信博主或者在评论区指出 💬💬💬。
如果大家有更优的时间、空间复杂度的方法,欢迎评论区交流。
最后,感谢您的阅读,如果有所收获的话可以给我点一个 👍 哦。