首页 > 其他分享 >华为OD机试真题---整数对最小和

华为OD机试真题---整数对最小和

时间:2024-10-04 10:49:36浏览次数:3  
标签:OD 真题 int array2 array1 元素 最小 --- 数组

题目描述

给定两个整数数组array1array2,数组元素按升序排列。假设从array1array2中分别取出一个元素可构成一对元素。现在需要取出K个元素对(即从两个数组中各取一个元素组成一个对,共取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

解题思路

  1. 暴力枚举法

    • 双重循环遍历array1array2的所有元素对,记录它们的和。
    • 将所有可能的和排序,取前K个和的最小值。
    • 但这种方法的时间复杂度较高,为O(n^2 log(n^2)),其中n为数组的大小。
  2. 双指针法结合贪心策略(优化方法):

    • 利用数组的有序性,使用双指针从头开始遍历两个数组。
    • 每次选择两个指针指向的元素和中较小的一个,将其加入答案中,并将所在数组的指针向后移动一位。
    • 使用一个数据结构(如最小堆)来维护当前选取的元素对和以及对应的数组下标,以确保每次都能选择到和最小的元素对。
    • 但这种方法需要额外的空间来存储元素对和及其下标,且当K接近n^2时,算法效率可能较低。
  3. 最小堆优化

    • 初始时,将array1的第一个元素与array2的所有元素配对,并将这些配对的和以及对应的array1array2的下标插入最小堆中。
    • 每次从堆中取出和最小的元素对,将其和加入答案中,并将该元素对对应的array1的下一个元素与array2的当前元素(或下一个未使用的元素)组合并插入堆中。
    • 重复上述步骤,直到从堆中取出了K个元素对。
    • 这种方法的时间复杂度较低,为O(k log n),其中n为数组的大小,且空间复杂度也相对较低。

示例代码(最小堆优化)


import java.util.PriorityQueue;
import java.util.Scanner;

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

        // 读取array1
        int m = scanner.nextInt();
        int[] array1 = new int[m];
        for (int i = 0; i < m; i++) {
            array1[i] = scanner.nextInt();
        }

        // 读取array2
        int n = scanner.nextInt();
        int[] array2 = new int[n];
        for (int i = 0; i < n; i++) {
            array2[i] = scanner.nextInt();
        }

        // 读取k
        int k = scanner.nextInt();

        // 调用方法计算最小和
        System.out.println(findMinSumOfKPairs(array1, array2, k));

        scanner.close();
    }

    public static int findMinSumOfKPairs(int[] array1, int[] array2, int k) {
        PriorityQueue<int[]> minHeap = new PriorityQueue<>((a, b) -> a[0] - b[0]);

        // 初始化最小堆,将array1的第一个元素与array2的所有元素配对并插入堆中
        for (int j = 0; j < array2.length && j < k; j++) {
            minHeap.offer(new int[]{array1[0] + array2[j], 0, j});
        }

        int sum = 0;
        while (k > 0) {
            int[] pair = minHeap.poll();
            assert pair != null;
            sum += pair[0];
            int i = pair[1];
            int j = pair[2];

            // 如果array1还有剩余元素,则将下一个元素与array2的当前元素配对并插入堆中
            if (i + 1 < array1.length) {
                minHeap.offer(new int[]{array1[i + 1] + array2[j], i + 1, j});
            }

            k--;
        }

        return sum;
    }
}

运行步骤解析:

3 1 1 2
3 1 2 3
2

我们可以按照以下步骤解析并运行算法来求解整数对的最小和。

输入解析

  1. 第一行表示数组array1的大小为3,元素为1, 1, 2。
  2. 第二行表示数组array2的大小为3,元素为1, 2, 3。
  3. 第三行表示需要取出的元素对数量k为2。

算法步骤

我们将使用最小堆优化的方法来求解这个问题。

  1. 初始化最小堆

    • array1的第一个元素1与array2的所有元素(1, 2, 3)配对,并将这些配对的和(2, 3, 4)以及对应的array1array2的下标(0, 0), (0, 1), (0, 2)插入最小堆中。
    • 最小堆中的元素现在为:[(2, 0, 0), (3, 0, 1), (4, 0, 2)](注意:这里只展示了和与下标,实际在Java代码中会使用一个数组或对象来表示这些信息)。
  2. 从最小堆中取出元素对

    • 取出和最小的元素对(2, 0, 0),将其和2加入结果sum中,此时sum=2。
    • 更新最小堆:由于我们已经使用了array1的第0个元素和array2的第0个元素,我们需要将array1的第1个元素(也是1,因为array1中有重复元素)与array2的第0个元素配对,并插入堆中。即插入(2, 1, 0)。
    • 最小堆更新后为:[(3, 0, 1), (4, 0, 2), (2, 1, 0)]。
  3. 继续取出元素对

    • 再次取出和最小的元素对(2, 1, 0),将其和2加入结果sum中,此时sum=4。
    • 由于k已经为1(原本为2,已经取出了一对),我们只需要再取一对即可。但在这个例子中,为了完整性,我们假设k仍然大于0并继续操作(在实际代码中会有k的递减和检查)。
    • 由于我们已经使用了array1的前两个元素和array2的第0个元素,理论上我们应该继续将array1的下一个未使用元素与array2的当前或下一个未使用元素配对。但在这个例子中,由于k已经足够,我们可以停止。

然而,在这个特定的例子中,由于array1有重复元素,并且我们只需要取两对,所以实际上我们不需要继续扩展堆。但为了说明算法的一般性,我们展示了如何继续操作。

  1. 如果k仍然大于0,我们会继续从堆中取出元素对,并更新堆,直到k为0。

结果

对于给定的输入,我们只需要取出两对元素对即可,它们分别是(1, 1)和(1, 1),其和为2+2=4。但需要注意的是,由于array1中有重复元素,实际上我们取出的可能是(1来自array1的第0个位置, 1来自array2的第0个位置)和(1来自array1的第1个位置, 1来自array2的第0个位置)。在算法实现中,我们不需要关心具体是哪个位置的元素,只需要保证和最小即可。

注意事项

  • 在实际实现中,我们需要确保不会重复使用相同的元素对(即相同的下标组合)。但由于数组是有序的,并且我们使用最小堆来维护元素对和,所以每次从堆中取出的都是当前可选元素对中和最小的那一对。
  • 由于array1中有重复元素,所以可能存在多个元素对具有相同的和。在这种情况下,算法仍然有效,因为它会始终选择当前可选元素对中和最小的那一对(即使有多对具有相同的和)。

最终,对于给定的输入,算法将输出4作为整数对的最小和。

标签:OD,真题,int,array2,array1,元素,最小,---,数组
From: https://blog.csdn.net/lbp0123456/article/details/142652409

相关文章

  • 华为OD机试真题---第k个排列
    针对华为OD机试真题中的“第k个排列”问题,以下是对题目的详细解析及解答方法:题目描述给定参数n,从1到n会有n个整数:1,2,3,…,n。这n个数字共有n!种排列。按大小顺序升序列出所有排列的情况,并一一标记。给定n和k,返回第k个排列。输入与输出输入:第一行为n,给定n的范围是......
  • 测试H7-TOOL的CANFD助手J1939批量数据传输连续运行30个小时稳定不丢包
    根据客户需求做的一个不断电连续运行测试。测试条件1、H7-TOOL的CAN/CANFD助手控制一个节点设备2、使用J1939协议3、经典CAN方式,波特率250KbpsJ1939测试命令,250ms一次发送接收测试昨天下午三点到今晚9点半,共计30个小时不断电连续测试,实时记录的文件:现在还在持续运行的......
  • C# - 异步编程 - BackgroundWorker 类
    后台线程,BackgroundWorker类用于创建一个线程,在后台持续运行以完成某项工作,并不时地与主线程通信。BackgroundWorker类的属性,方法与事件。属性:WorkerReportsProgress:设置后台任务是否可以把它的进度汇报给主线程。WorkerSupportsCancellation:是否支持从主线程取消。IsB......
  • Codeforces Round 972 (Div. 2)
    一万一参赛,VP赛时136A.SimplePalindrome简单构造题。字母集是5,相同字母间一定构成若干回文子串。将相同字母排列在一起,则只有相同字母可以构成回文子串。显然,优先添加较少的字母即可。#include<bits/stdc++.h>usingnamespacestd;intT,n;chars[5]={'a','e','i......
  • CSP-J/S2024总结
    CSP-J/S2024游记初赛前记今年最后一年J了...希望圆我个2年都没有实现的J一等梦还有希望S考好点期待1=day-1考完不放假,然后月考,高兴坏了day1没什么好说的,行就行,不行就AFO(假CSP-J本来就打算摆烂,所以不慌因为是最后一个考场,只有26人,赢!嗯?开局放int?完辣!组合题放那......
  • Debuggers 1012:Introductory GDB
    OpenSecurityTraining2LearningPaths:VulnerabilityHunting&Exploitationpython:https://www.learnpython.org/路径图:https://ost2.fyi/OST2_LP_Vulns_Exploits.pdfDebuggers1012:IntroductoryGDB(与python)-->Architecture1001:x86-64Assembly-->R......
  • Cisco Secure Network Analytics 7.5.1 - 领先的网络检测和响应 (NDR) 解决方案
    CiscoSecureNetworkAnalytics7.5.1-领先的网络检测和响应(NDR)解决方案SecureNetworkAnalytics(formerlyStealthwatch)-NetworkVisibilityandSegmentation请访问原文链接:https://sysin.org/blog/cisco-secure-network-analytics/,查看最新版。原创作品,转载请保......
  • 24.10.4-2
    虽然想着不就是没有朋友吗,我怎么能为这点事情去送死呢,但是内心还是非常不舒服我的人生意义到底是什么财富,美食,兴趣?这些其实完全不感兴趣食物只是维持生理活动的必需品罢了,如果不是必须吃,我宁愿不吃。财富所能满足的人不是欲望十足,就是野心十足,反正对我来说也只是维持生命的必......
  • <动态规划>Leetcode96.不同的二叉搜索树
    给你一个整数n,求恰由n个节点组成且节点值从1到n互不相同的二叉搜索树有多少种?返回满足题意的二叉搜索树的种数。解题步骤如下:二叉搜素树的相关概念寻找规律思路建立代码实现1.二叉搜索树的相关概念①:若左子树不空,则左子树所有节点的值均小于它的根节点的值。......
  • 10.3 - AM - 模拟赛 总结
    复盘T1很水,一道异或求和,但是某两位仁兄因没打括号而死。T2很水,一道字符串处理,但是我和某位仁兄因没特判而死(虽然没有hack掉我,所以我理论上还是满分)。T3不水,看了很久,没想出来,自闭了就去看了T4。发现也做不出来。此时我出去晃了一圈,大概是不知道从哪里看到了一个“二”字......