2026-04-12:统计合格元素的数目。用go语言,给定一个长度为 n 的整数数组 nums,以及一个整数 k。
我们把数组中的某个元素记为“合格”,当且仅当:在数组中比它大的元素数量不少于 k 个(也就是严格大于该元素的数至少有 k 个)。
请统计并返回数组里所有“合格”元素的数量。
1 <= n == nums.length <= 100000。
1 <= nums[i] <= 1000000000。
0 <= k < n。
输入: nums = [3,1,2], k = 1。
输出: 2。
解释:
元素 1 和 2 均有至少 k = 1 个元素大于它们。
没有元素比 3 更大。因此答案是 2。
代码执行过程详细分步描述
第一步:处理特殊边界条件
代码首先判断 k 是否等于 0:
- 题目中
k=1,不满足k==0,跳过该分支; - 这个分支的作用是:如果
k=0,所有元素都满足「严格大于它的数至少0个」,直接返回数组总长度即可。
第二步:对数组进行升序排序
代码调用排序函数对原数组升序排列:
- 原数组:
[3, 1, 2] - 排序后数组:
[1, 2, 3] - 排序的目的:方便快速找到「第k大的元素」,进而判断哪些元素是合格元素。
第三步:定位「第k大的元素」
- 先计算数组长度
n=3; - 第k大的元素,在升序排序后的数组中,位置是
n-k(索引从0开始); - 代入计算:
n-k = 3-1 = 2,即排序后数组索引为2的元素; - 排序数组
[1,2,3]索引2的元素是3,这就是第1大的元素。
第四步:统计「合格元素」的数量
题目定义:严格大于该元素的数至少有k个 → 该元素为合格元素。
- 升序排序后,所有小于「第k大元素」的数,都满足「至少有k个元素比它大」;
- 代码通过查找函数,统计排序数组中小于「第k大元素(3)」的元素个数;
- 排序数组
[1,2,3]中小于3的元素是1、2,总数量为2;
第五步:返回结果并输出
将统计的数量2作为结果返回,最终输出结果为2,与题目要求一致。
时间复杂度与额外空间复杂度分析
1. 总时间复杂度
代码的核心操作分为两部分:
- 数组排序:Go 语言内置的排序算法时间复杂度为 O(n log n)(n是数组长度);
- 查找元素个数:
sort.SearchInts是二分查找,时间复杂度为 O(log n); - 其他操作(赋值、判断)都是常数时间 O(1)。
总时间复杂度由最高量级的操作决定,因此: ✅ 总时间复杂度:O(n log n)
2. 总额外空间复杂度
额外空间指:除了输入数组本身外,代码执行过程中额外开辟的内存空间。
- 排序操作:Go 语言的切片排序是原地排序,仅使用常数级的临时变量,不额外开辟数组空间;
- 代码中仅定义了
n、result等几个变量,占用空间与数组长度n无关;
✅ 总额外空间复杂度:O(1)(常数级空间)
总结
- 执行核心流程:判断k=0→数组升序排序→找到第k大元素→统计小于该元素的数量→返回结果;
- 时间复杂度:O(n log n)(主要耗时在排序);
- 额外空间复杂度:O(1)(原地操作,无额外大空间开销)。
Go完整代码如下:
package main
import (
"fmt"
"slices"
"sort"
)
func countElements(nums []int, k int) int {
n := len(nums)
if k == 0 {
return n
}
slices.Sort(nums)
return sort.SearchInts(nums, nums[n-k]) // 小于第 k 大的元素个数
}
func main() {
nums := []int{3, 1, 2}
k := 1
result := countElements(nums, k)
fmt.Println(result)
}
Python完整代码如下:
# -*-coding:utf-8-*-
from bisect import bisect_right
from typing import List
def count_elements(nums: List[int], k: int) -> int:
n = len(nums)
if k == 0:
return n
nums.sort()
# bisect_right returns the index where to insert to keep sorted order,
# which gives the count of elements <= target
# Here we want the number of elements < the k-th largest element
# The k-th largest element is at index n-k
target = nums[n - k]
return bisect_right(nums, target - 1)
def main():
nums = [3, 1, 2]
k = 1
result = count_elements(nums, k)
print(result)
if __name__ == "__main__":
main()
C++完整代码如下:
#include <iostream>
#include <vector>
#include <algorithm>
int countElements(std::vector<int>& nums, int k) {
int n = nums.size();
if (k == 0) {
return n;
}
std::sort(nums.begin(), nums.end());
// Get the k-th largest element
int kth_largest = nums[n - k];
// Count elements strictly less than kth_largest
int count = 0;
for (int num : nums) {
if (num < kth_largest) {
count++;
} else {
break; // Since array is sorted, we can break early
}
}
return count;
}
int main() {
std::vector<int> nums = {3, 1, 2};
int k = 1;
int result = countElements(nums, k);
std::cout << result << std::endl;
return 0;
}