题目描述与示例

题目描述

给定一个数组,编写一个函数来计算它的最大N个数与最小N个数的和。你需要对数组进行去重。

输入描述

第一行输入MM标识数组大小

第二行输入M个数,标识数组内容

第三行输入NN表达需要计算的最大、最小N个数

输出描述

输出最大N个数与最小N个数的和。

补充说明

数组中数字范围[0,1000]

最大N个数与最小N个数不能有重叠,如有重叠返回-1

示例

输入

5
95 88 83 64 100
2

输出

342

解题思路

直白、简单的题目。主要考察以下几个知识点

  1. 哈希集合去重
  2. 去重后的结果再次排序得到新列表lst_new
  3. lst_new的长度必须大于2*N
  4. 计算最大的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++

“`C++
#include <iostream>
#include <vector>
#include <set>
#include <algorithm>

using namespace std;

int main() {
int m, n;
cin >> m;

<pre><code>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;
</code></pre>

}

“`

时空复杂度

时间复杂度:O(MlogM)。排序所需时间复杂度

空间复杂度:O(M)

说明

华为OD机试有三道题⽬,第⼀道和第⼆道属于简单或中等题,分值为 100 分,第三道为中等或困难题,分值为 200分,总分为 400 分。

机试分数越⾼评级越⾼,⼯资也就越⾼。

关于华为 OD 机试更加详细的介绍可以查看这篇⽂章:华为OD机考须知

关于机考题目汇总可以看这篇文章:华为OD机试真题 2023 A+B+C+D卷 + 2024新卷(Python&Java&C++)⽬录汇总(每⽇更新)