OD统一考试(C卷)
分值: 100分
题解: Java / Python / C++
题目描述
给定一个数组,编写一个函数来计算它的最大N个数与最小N个数的和。你需要对数组进行去重。
说明:
数组中数字范围[0, 1000]
最大N个数与最小N个数不能有重叠,如有重叠,输入非法返回-1
输入非法返回-1
输入描述
第一行输入M, M标识数组大小
第二行输入M个数,标识数组内容
第三行输入N,N表示需要计算的最大、最小N个数
输出描述
输出最大N个数与最小N个数的和。
示例1
输入
5
95 88 83 64 100
2输出
342说明
最大2个数[100,95],最小2个数[83,64], 输出为342。
示例2
输入
5
3 2 3 4 2
2输出
-1说明
最大2个数[4,3],最小2个数[3,2], 有重叠输出为-1。
题解
题目主要要求计算给定数组中最大N个数和最小N个数的和,同时需要处理可能的重叠情况。给出了 Java、Python 和 C++ 的解法,它们的基本思路是一致的,通过排序数组并使用两个集合(最小N个数的集合和最大N个数的集合)来进行计算。以下是对解法的总结:
- 排序数组:首先对输入的数组进行排序,这样方便后续取最大和最小的N个数。
- 使用两个集合:分别维护一个最小N个数的集合和最大N个数的集合。这里使用集合是为了去重,确保不同的数值只会计算一次。
- 检查重叠:在计算最小N个数和最大N个数的和之前,检查两个集合是否有交集。如果有交集,说明存在重叠,返回-1。
- 计算和:如果没有重叠,计算最小N个数和最大N个数的和,并输出。
注意事项:
- 在 C++ 中,需要进行类型转换来避免警告,特别是在比较
minSet.size()
和maxSet.size()
与n
时。- 在 Java 中,使用
Collections.disjoint
方法来检查两个集合是否有交集。这个问题的解法思路相对清晰,通过排序和集合的操作,能够较为高效地解决问题。
Java
import java.util.*;/*** @author code5bug*/
public class Main {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);int m = scanner.nextInt();int[] arr = new int[m];for (int i = 0; i < m; i++) {arr[i] = scanner.nextInt();}int n = scanner.nextInt();Arrays.sort(arr);// 最小的N个数, 最大的N个数Set<Integer> minSet = new HashSet<>();Set<Integer> maxSet = new HashSet<>();for (int i = 0; i < m; i++) {if (minSet.size() < n) {minSet.add(arr[i]);}if (maxSet.size() < n) {maxSet.add(arr[m - 1 - i]);}}if (!Collections.disjoint(minSet, maxSet)) { // 比较两个集合是否有交集System.out.println(-1);} else {int sum = minSet.stream().mapToInt(Integer::intValue).sum() + maxSet.stream().mapToInt(Integer::intValue).sum();System.out.println(sum);}}
}
Python
m = int(input())
arr = list(map(int, input().split()))
n = int(input())
arr.sort()# 最小的N个数, 最大的N个数
min_n, max_n = set(), set()
for i in range(m):if len(min_n) < n:min_n.add(arr[i])if len(max_n) < n:max_n.add(arr[m-1-i])if set(min_n) & set(max_n):print(-1)
else:print(sum(min_n) + sum(max_n))
C++
#include <bits/stdc++.h>using namespace std;int main() {int m;cin >> m;vector<int> arr(m);for (int i = 0; i < m; i++) {cin >> arr[i];}int n;cin >> n;sort(arr.begin(), arr.end());// 最小的N个数, 最大的N个数set<int> minSet, maxSet;for (int i = 0; i < m; i++) {if (minSet.size() < static_cast<size_t>(n)) {minSet.insert(arr[i]);}if (maxSet.size() < static_cast<size_t>(n)) {maxSet.insert(arr[m - 1 - i]);}}// 比较两个集合是否有交集bool hasIntersection = false;for (int num : minSet) {if (maxSet.find(num) != maxSet.end()) {hasIntersection = true;break;}}if (hasIntersection) {cout << -1 << endl;} else {int sum = 0;for (int num : minSet) {sum += num;}for (int num : maxSet) {sum += num;}cout << sum << endl;}return 0;
}
❤️华为OD机试面试交流群(每日真题分享): 加V时备注“华为od加群”
🙏整理题解不易, 如果有帮助到您,请给点个赞 ❤️ 和收藏 ⭐,让更多的人看到。🙏🙏🙏