Medium

题目描述

给你一个下标从 0 开始的整数数组 nums。对于每个下标 i1 <= i <= nums.length - 2),nums[i]美丽值 等于:

  • 2,如果对于所有 0 <= j < ii < 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^5
  • 1 <= nums[i] <= 10^5

解题思路

解题思路

这道题需要判断数组中每个位置的"美丽值",关键在于理解三种美丽值的判断条件:

  1. 美丽值 = 2:当前元素严格大于左侧所有元素,且严格小于右侧所有元素
  2. 美丽值 = 1:当前元素在相邻的三个元素中呈递增趋势(但不满足条件1)
  3. 美丽值 = 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)

相关题目