【哈希集合】2024D-最大N个数与最小N个数的和
【哈希集合】2024D-最大N个数与最小N个数的和
题目描述与示例
本题练习地址:https://www.algomooc.com/problem/P2705
题目描述
给定一个数组,编写一个函数来计算它的最大N
个数与最小N
个数的和。你需要对数组进行去重。
输入描述
第一行输入M
, M
标识数组大小
第二行输入M
个数,标识数组内容
第三行输入N
,N
表达需要计算的最大、最小N
个数
输出描述
输出最大N
个数与最小N
个数的和。
补充说明
数组中数字范围[0,1000]
最大N
个数与最小N
个数不能有重叠,如有重叠返回-1
示例
输入
5
95 88 83 64 100
2
输出
342
解题思路
直白、简单的题目。主要考察以下几个知识点
- 哈希集合去重
- 去重后的结果再次排序得到新列表
lst_new
lst_new
的长度必须大于2*N
- 计算最大的
N
个数和最小的N
个数的和
代码
Python
# 题目:2023C-最大N个数与最小N个数的和
# 分值:100
# 作者:闭着眼睛学数理化
# 算法:哈希集合,排序
# 代码看不懂的地方,请直接在群上提问
m = int(input())
lst = list(map(int, input().split()))
n = int(input())
# 使用set进行去重,然后对去重后的结果进行排序
lst_new = sorted(set(lst))
# 如果lst_new的长度小于2*n
# 说明最大N个数和最小N个数出现了重叠,输出-1
if len(lst_new) < 2*n:
print(-1)
# 否则,使用切片和sum(),计算最大N个数和最小N个数的和
else:
print(sum(lst_new[:n]) + sum(lst_new[len(lst_new)-n:]))
Java
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int m = scanner.nextInt();
List<Integer> lst = new ArrayList<>();
for (int i = 0; i < m; ++i) {
lst.add(scanner.nextInt());
}
int n = scanner.nextInt();
// 使用 Set 进行去重,并对其进行排序
Set<Integer> uniqueSet = new TreeSet<>(lst);
List<Integer> lstNew = new ArrayList<>(uniqueSet);
if (lstNew.size() < 2 * n) {
System.out.println(-1);
} else {
long sum = 0;
for (int i = 0; i < n; ++i) {
sum += lstNew.get(i) + lstNew.get(lstNew.size() - 1 - i);
}
System.out.println(sum);
}
}
}
C++
#include <iostream>
#include <vector>
#include <set>
#include <algorithm>
using namespace std;
int main() {
int m, n;
cin >> m;
vector<int> lst(m);
for (int i = 0; i < m; ++i) {
cin >> lst[i];
}
cin >> n;
// 使用 set 进行去重,并对其进行排序
set<int> uniqueSet(lst.begin(), lst.end());
vector<int> lstNew(uniqueSet.begin(), uniqueSet.end());
sort(lstNew.begin(), lstNew.end());
if (lstNew.size() < 2 * n) {
cout << -1 << endl;
} else {
long long sum = 0;
for (int i = 0; i < n; ++i) {
sum += lstNew[i] + lstNew[lstNew.size() - 1 - i];
}
cout << sum << endl;
}
return 0;
}
时空复杂度
时间复杂度:O(MlogM)
。排序所需时间复杂度
空间复杂度:O(M)
。