Easy
题目描述
给你一个下标从 0 开始的整数数组 nums ,其长度是 2 的幂 。
对 nums 应用以下算法:
- 设
n等于nums的长度,如果n == 1,终止 进程。否则,创建 一个新的整数数组newNums,新数组长度为n / 2,下标从 0 开始。 - 对于满足
0 <= i < n / 2的每个 偶数 下标i,将newNums[i]赋值 为min(nums[2 * i], nums[2 * i + 1])。 - 对于满足
0 <= i < n / 2的每个 奇数 下标i,将newNums[i]赋值 为max(nums[2 * i], nums[2 * i + 1])。 - 用
newNums替换nums。 - 从步骤 1 开始 重复 整个过程。
返回在应用算法后 nums 中剩下的那个数字。
示例 1:
输入:nums = [1,3,5,2,4,8,2,2]
输出:1
解释:重复应用算法会得到下述数组。
第一轮:nums = [1,5,4,2]
第二轮:nums = [1,4]
第三轮:nums = [1]
1 是最后剩下的那个数字,返回 1 。
示例 2:
输入:nums = [3]
输出:3
解释:3 就是最后剩下的那个数字,返回 3 。
提示:
1 <= nums.length <= 10241 <= nums[i] <= 10^9nums.length是2的幂
解题思路
这道题要求我们模拟一个递归过程,每轮都将数组长度缩减一半,直到只剩一个元素。
核心思路:
- 直接模拟:按照题目要求逐步执行算法,每轮创建新数组,根据索引奇偶性选择min或max操作
- 原地操作优化:可以在原数组上直接修改,避免创建新数组,节省空间
算法流程:
- 当数组长度大于1时,进入循环
- 遍历当前数组的前半部分(新数组的位置)
- 对于新数组的偶数索引位置:取对应两个元素的最小值
- 对于新数组的奇数索引位置:取对应两个元素的最大值
- 更新数组长度为原来的一半
- 重复直到只剩一个元素
复杂度特点: 由于每轮数组长度都减半,总共只需要O(log n)轮,每轮处理O(n)个元素,但由于n在递减,总时间复杂度仍为O(n)。
这是一个典型的模拟题,关键是理解题意并正确实现算法逻辑。
代码实现
class Solution {
public:
int minMaxGame(vector<int>& nums) {
int n = nums.size();
while (n > 1) {
for (int i = 0; i < n / 2; i++) {
if (i % 2 == 0) {
nums[i] = min(nums[2 * i], nums[2 * i + 1]);
} else {
nums[i] = max(nums[2 * i], nums[2 * i + 1]);
}
}
n /= 2;
}
return nums[0];
}
};
class Solution:
def minMaxGame(self, nums: List[int]) -> int:
n = len(nums)
while n > 1:
for i in range(n // 2):
if i % 2 == 0:
nums[i] = min(nums[2 * i], nums[2 * i + 1])
else:
nums[i] = max(nums[2 * i], nums[2 * i + 1])
n //= 2
return nums[0]
public class Solution {
public int MinMaxGame(int[] nums) {
int n = nums.Length;
while (n > 1) {
for (int i = 0; i < n / 2; i++) {
if (i % 2 == 0) {
nums[i] = Math.Min(nums[2 * i], nums[2 * i + 1]);
} else {
nums[i] = Math.Max(nums[2 * i], nums[2 * i + 1]);
}
}
n /= 2;
}
return nums[0];
}
}
/**
* @param {number[]} nums
* @return {number}
*/
var minMaxGame = function(nums) {
while (nums.length > 1) {
let newNums = [];
for (let i = 0; i < nums.length / 2; i++) {
if (i % 2 === 0) {
newNums[i] = Math.min(nums[2 * i], nums[2 * i + 1]);
} else {
newNums[i] = Math.max(nums[2 * i], nums[2 * i + 1]);
}
}
nums = newNums;
}
return nums[0];
};
复杂度分析
| 复杂度类型 | 值 | 说明 |
|---|---|---|
| 时间复杂度 | O(n) | 虽然有log n轮,但每轮处理的元素数量递减,总计算量为n + n/2 + n/4 + … ≈ 2n |
| 空间复杂度 | O(1) | 原地修改数组,不需要额外空间 |
相关题目
. Elimination Game (Medium)
. Find Triangular Sum of an Array (Medium)