【Py/Java/C++三种语言OD独家2024D卷真题】20天拿下华为OD笔试之【模拟】2024D-整数对最小和【欧弟算法】全网注释最详细分类最全的华为OD真题题解

可上 欧弟OJ系统 练习华子OD、大厂真题
绿色聊天软件戳 od1441了解算法冲刺训练(备注【CSDN】否则不通过)

从2024年4月15号开始,OD机考全部配置为2024D卷
注意两个关键点:

  1. 会遇到C卷复用题。虽然可能存在幸存者偏差,但肯定还会有一大部分的旧题。
  2. 现在又支持做完题目之后倒回去改了。就是可以先做200的再做100的,然后可以反复提交。
    在这里插入图片描述

题目描述与示例

题目描述

给定两个整数数组array1array2,数组元素按升序排列。假设从array1array2中分别取出一个元素可构成一对元素,现在需要取出k对元素,并对取出的所有元素求和计算和的最小值。

注意:两对元素如果对应于array1array2中的两个下标均相同,则视为同一对元素。

输入描述

输入两行数组array1array2,每行首个数字为数组大小size(0 < size <= 100)

0 < array1[i] <= 1000
0 < array2[i] <= 1000

接下来一行为正整数k

0 < k <= array1.size()*array2.size()

输出描述

满足要求的最小和

示例

输入

3 1 1 2
3 1 2 3
2

输出

4

说明

用例中,需要取2对元素

取第一个数组第0个元素与第二个数组第0个元素组成1对元素[1,1];

取第一个数组第1个元素与第二个数组第0个元素组成1对元素[1,1];

求和为1+1+1+1=4,为满足要求的最小和。

解题思路

读懂题目就能完成这题。

因为数据量不大,两个数组的长度均不超过100,所以整数对最多的数目仅为100*100 = 10000

O(n1n2log(n1n2))的时间复杂度是可以通过这个题目的。

整体流程即为

  1. 输入数据,初始化列表ans
  2. 双重遍历两个数组,获得所有的整数对的和nums1[i] + nums2[j],加入ans中。该过程的时间复杂度为O(n1n2)
  3. ans进行从小到大的排序,该过程的时间复杂度为O(n1n2log(n1n2))
  4. ans中前k个元素进行求和并输出

取前k个元素的过程可以用优先队列进行优化,可以将排序的时间复杂度降到O(klogk)

代码

python

# 题目:【模拟】2024D-整数对最小和
# 分值:100
# 作者:许老师-闭着眼睛学数理化
# 算法:模拟
# 代码看不懂的地方,请直接在群上提问


# 输入数组长度n1,数组nums1
lst1 = list(map(int, input().split()))
n1 = lst1[0]
nums1 = lst1[1:]

# 输入数组长度n2,数组nums2
lst2 = list(map(int, input().split()))
n2 = lst2[0]
nums2 = lst2[1:]

# 输入k
k = int(input())

ans = list()

# 双重遍历所有整数对
for i in range(n1):
    for j in range(n2):
        # 将整数对的和加入ans中
        ans.append(nums1[i] + nums2[j])

# 对ans进行从小到大排序
ans.sort()
# 取ans中前k个元素进行求和并输出,即为答案
print(sum(ans[:k]))

java

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        // 输入数组长度n1,数组nums1
        String[] input1 = scanner.nextLine().split(" ");
        int n1 = Integer.parseInt(input1[0]);
        int[] nums1 = new int[n1];
        for (int i = 0; i < n1; i++) {
            nums1[i] = Integer.parseInt(input1[i + 1]);
        }

        // 输入数组长度n2,数组nums2
        String[] input2 = scanner.nextLine().split(" ");
        int n2 = Integer.parseInt(input2[0]);
        int[] nums2 = new int[n2];
        for (int i = 0; i < n2; i++) {
            nums2[i] = Integer.parseInt(input2[i + 1]);
        }

        // 输入k
        int k = scanner.nextInt();

        List<Integer> ans = new ArrayList<>();

        // 双重遍历所有整数对
        for (int i = 0; i < n1; i++) {
            for (int j = 0; j < n2; j++) {
                // 将整数对的和加入ans中
                ans.add(nums1[i] + nums2[j]);
            }
        }

        // 对ans进行从小到大排序
        Collections.sort(ans);
        // 取ans中前k个元素进行求和并输出,即为答案
        int sum = 0;
        for (int i = 0; i < k; i++) {
            sum += ans.get(i);
        }

        System.out.println(sum);
        scanner.close();
    }
}

cpp

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int main() {
    // 输入数组长度n1,数组nums1
    int n1;
    cin >> n1;
    vector<int> nums1(n1);
    for (int i = 0; i < n1; ++i) {
        cin >> nums1[i];
    }

    // 输入数组长度n2,数组nums2
    int n2;
    cin >> n2;
    vector<int> nums2(n2);
    for (int i = 0; i < n2; ++i) {
        cin >> nums2[i];
    }

    // 输入k
    int k;
    cin >> k;

    vector<int> ans;

    // 双重遍历所有整数对
    for (int i = 0; i < n1; ++i) {
        for (int j = 0; j < n2; ++j) {
            // 将整数对的和加入ans中
            ans.push_back(nums1[i] + nums2[j]);
        }
    }

    // 对ans进行从小到大排序
    sort(ans.begin(), ans.end());
    // 取ans中前k个元素进行求和并输出,即为答案
    int sum = 0;
    for (int i = 0; i < k; ++i) {
        sum += ans[i];
    }

    cout << sum << endl;

    return 0;
}

时空复杂度

时间复杂度:O(n1n2log(n1n2))。排序所需的时间复杂度。

空间复杂度:O(1)。仅需若干常数变量


华为OD算法/大厂面试高频题算法练习冲刺训练

  • 华为OD算法/大厂面试高频题算法冲刺训练目前开始常态化报名!目前已服务300+同学成功上岸!

  • 课程讲师为全网50w+粉丝编程博主@吴师兄学算法 以及小红书头部编程博主@闭着眼睛学数理化

  • 每期人数维持在20人内,保证能够最大限度地满足到每一个同学的需求,达到和1v1同样的学习效果!

  • 60+天陪伴式学习,40+直播课时,300+动画图解视频,300+LeetCode经典题,200+华为OD真题/大厂真题,还有简历修改、模拟面试、专属HR对接将为你解锁

  • 可上全网独家的欧弟OJ系统练习华子OD、大厂真题

  • 可查看链接 大厂真题汇总 & OD真题汇总(持续更新)

  • 绿色聊天软件戳 od1336了解更多

  • 14
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值