Medium
题目描述
给你一个下标从 0 开始的整数数组 nums。对于每个下标 i(1 <= i <= nums.length - 2),nums[i] 的 美丽值 等于:
- 2,如果对于所有
0 <= j < i且i < k <= nums.length - 1,都有nums[j] < nums[i] < nums[k] - 1,如果
nums[i - 1] < nums[i] < nums[i + 1]且不满足前面的条件 - 0,如果上述条件都不满足
返回范围 1 <= i <= nums.length - 2 中所有 nums[i] 的美丽值之和。
示例 1:
输入:nums = [1,2,3]
输出:2
解释:对于范围 1 <= i <= 1 中的每个下标 i:
- nums[1] 的美丽值等于 2
示例 2:
输入:nums = [2,4,6,4]
输出:1
解释:对于范围 1 <= i <= 2 中的每个下标 i:
- nums[1] 的美丽值等于 1
- nums[2] 的美丽值等于 0
示例 3:
输入:nums = [3,2,1]
输出:0
解释:对于范围 1 <= i <= 1 中的每个下标 i:
- nums[1] 的美丽值等于 0
提示:
3 <= nums.length <= 10^51 <= nums[i] <= 10^5
解题思路
解题思路
这道题需要判断数组中每个位置的"美丽值",关键在于理解三种美丽值的判断条件:
- 美丽值 = 2:当前元素严格大于左侧所有元素,且严格小于右侧所有元素
- 美丽值 = 1:当前元素在相邻的三个元素中呈递增趋势(但不满足条件1)
- 美丽值 = 0:其他情况
核心思路是预处理前缀最大值和后缀最小值:
prefixMax[i]:记录位置i左侧所有元素的最大值suffixMin[i]:记录位置i右侧所有元素的最小值
这样对于位置 i:
- 如果
prefixMax[i] < nums[i] < suffixMin[i],美丽值为 2 - 否则如果
nums[i-1] < nums[i] < nums[i+1],美丽值为 1 - 其他情况美丽值为 0
时间复杂度为 O(n),空间复杂度为 O(n)。这种方法避免了对每个位置重复计算左右范围的最值,大大提高了效率。
推荐解法:使用前缀最大值和后缀最小值数组的预处理方法。
代码实现
class Solution {
public:
int sumOfBeauties(vector<int>& nums) {
int n = nums.size();
vector<int> prefixMax(n), suffixMin(n);
// 计算前缀最大值
prefixMax[0] = nums[0];
for (int i = 1; i < n; i++) {
prefixMax[i] = max(prefixMax[i - 1], nums[i]);
}
// 计算后缀最小值
suffixMin[n - 1] = nums[n - 1];
for (int i = n - 2; i >= 0; i--) {
suffixMin[i] = min(suffixMin[i + 1], nums[i]);
}
int result = 0;
for (int i = 1; i < n - 1; i++) {
if (prefixMax[i - 1] < nums[i] && nums[i] < suffixMin[i + 1]) {
result += 2;
} else if (nums[i - 1] < nums[i] && nums[i] < nums[i + 1]) {
result += 1;
}
}
return result;
}
};
class Solution:
def sumOfBeauties(self, nums: List[int]) -> int:
n = len(nums)
# 计算前缀最大值
prefix_max = [0] * n
prefix_max[0] = nums[0]
for i in range(1, n):
prefix_max[i] = max(prefix_max[i - 1], nums[i])
# 计算后缀最小值
suffix_min = [0] * n
suffix_min[n - 1] = nums[n - 1]
for i in range(n - 2, -1, -1):
suffix_min[i] = min(suffix_min[i + 1], nums[i])
result = 0
for i in range(1, n - 1):
if prefix_max[i - 1] < nums[i] < suffix_min[i + 1]:
result += 2
elif nums[i - 1] < nums[i] < nums[i + 1]:
result += 1
return result
public class Solution {
public int SumOfBeauties(int[] nums) {
int n = nums.Length;
int[] prefixMax = new int[n];
int[] suffixMin = new int[n];
// 计算前缀最大值
prefixMax[0] = nums[0];
for (int i = 1; i < n; i++) {
prefixMax[i] = Math.Max(prefixMax[i - 1], nums[i]);
}
// 计算后缀最小值
suffixMin[n - 1] = nums[n - 1];
for (int i = n - 2; i >= 0; i--) {
suffixMin[i] = Math.Min(suffixMin[i + 1], nums[i]);
}
int result = 0;
for (int i = 1; i < n - 1; i++) {
if (prefixMax[i - 1] < nums[i] && nums[i] < suffixMin[i + 1]) {
result += 2;
} else if (nums[i - 1] < nums[i] && nums[i] < nums[i + 1]) {
result += 1;
}
}
return result;
}
}
var sumOfBeauties = function(nums) {
const n = nums.length;
const prefixMax = new Array(n);
const suffixMin = new Array(n);
// 计算前缀最大值
prefixMax[0] = nums[0];
for (let i = 1; i < n; i++) {
prefixMax[i] = Math.max(prefixMax[i - 1], nums[i]);
}
// 计算后缀最小值
suffixMin[n - 1] = nums[n - 1];
for (let i = n - 2; i >= 0; i--) {
suffixMin[i] = Math.min(suffixMin[i + 1], nums[i]);
}
let result = 0;
for (let i = 1; i < n - 1; i++) {
if (prefixMax[i - 1] < nums[i] && nums[i] < suffixMin[i + 1]) {
result += 2;
} else if (nums[i - 1] < nums[i] && nums[i] < nums[i + 1]) {
result += 1;
}
}
return result;
};
复杂度分析
| 复杂度类型 | 复杂度 |
|---|---|
| 时间复杂度 | O(n) |
| 空间复杂度 | O(n) |