Easy
题目描述
给你一个整数数组 nums ,返回在 nums 中同时具有一个严格较小元素和一个严格较大元素的元素数目。
示例 1:
输入:nums = [11,7,2,15]
输出:2
解释:元素 7 :严格较小元素是元素 2 ,严格较大元素是元素 11 。
元素 11 :严格较小元素是元素 7 ,严格较大元素是元素 15 。
总计有 2 个元素都有一个严格较小元素和一个严格较大元素。
示例 2:
输入:nums = [-3,3,3,90]
输出:2
解释:元素 3 :严格较小元素是元素 -3 ,严格较大元素是元素 90 。由于有两个元素的值为 3 ,总计有 2 个元素都有一个严格较小元素和一个严格较大元素。
提示:
1 <= nums.length <= 100-10^5 <= nums[i] <= 10^5
解题思路
这道题的核心思路是找出既不是最大值也不是最小值的元素个数。
分析过程:
- 对于一个元素要同时有严格较小和严格较大的元素,说明这个元素既不是数组中的最小值,也不是数组中的最大值
- 因此我们只需要统计数组中除了最大值和最小值以外的所有元素个数
解法思路:
- 直接统计法:找出数组的最大值和最小值,然后统计既不等于最大值也不等于最小值的元素个数
- 优化公式法:总元素个数减去最大值的个数再减去最小值的个数
需要注意的特殊情况:
- 如果数组中所有元素都相等,那么没有任何元素同时具有严格较小和严格较大的元素,答案为0
- 最大值和最小值可能相等(所有元素相等的情况)
推荐解法: 使用公式法,代码简洁且效率高。
代码实现
class Solution {
public:
int countElements(vector<int>& nums) {
int minVal = *min_element(nums.begin(), nums.end());
int maxVal = *max_element(nums.begin(), nums.end());
if (minVal == maxVal) {
return 0;
}
int count = 0;
for (int num : nums) {
if (num != minVal && num != maxVal) {
count++;
}
}
return count;
}
};
class Solution:
def countElements(self, nums: List[int]) -> int:
min_val = min(nums)
max_val = max(nums)
if min_val == max_val:
return 0
count = 0
for num in nums:
if num != min_val and num != max_val:
count += 1
return count
public class Solution {
public int CountElements(int[] nums) {
int minVal = nums.Min();
int maxVal = nums.Max();
if (minVal == maxVal) {
return 0;
}
int count = 0;
foreach (int num in nums) {
if (num != minVal && num != maxVal) {
count++;
}
}
return count;
}
}
var countElements = function(nums) {
const min = Math.min(...nums);
const max = Math.max(...nums);
let count = 0;
for (let num of nums) {
if (num > min && num < max) {
count++;
}
}
return count;
};
复杂度分析
| 复杂度类型 | 复杂度 | 说明 |
|---|---|---|
| 时间复杂度 | O(n) | 需要两次遍历数组:一次找最值,一次统计符合条件的元素 |
| 空间复杂度 | O(1) | 只使用常数额外空间存储最大值、最小值和计数器 |