找出两个整数数组中同时出现的整数 - 华为OD机试真题(A卷、JavaScript题解)

华为OD机试题库《C++》限时优惠 9.9

华为OD机试题库《Python》限时优惠 9.9

华为OD机试题库《JavaScript》限时优惠 9.9

针对刷题难,效率慢,我们提供一对一算法辅导, 针对个人情况定制化的提高计划(全称1V1效率更高)。

看不懂有疑问需要答疑辅导欢迎私VX: code5bug

华为OD机试

题目描述

现有两个整数数组,需要你找出两个数组中同时出现的整数,并按照如下要求输出:

1、 有同时出现的整数时,先按照同时出现次数(整数在两个数组中都出现并且出现次数较少的那个)进行归类,然后按照出现次数从小到大依次按行输出。

2、没有同时出现的整数时,输出NULL。

输入描述

第一行为第一个整数数组,第二行为第二个整数数组,每行数据中整数与整数之间以英文逗号分隔,整数的取值范围为[-200,200],数组长度的范围为[1,10000]之间的整数。

输出描述

按照出现次数从小到大依次按行输出,每行输出的格式为:出现次数:该出现次数下的整数升序排序的结果。

格式中的":"为英文冒号,整数间以英文逗号分隔。

示例1

输入:
5,3,6,-8,0,11
2,8,8,8,-1,15

输出:
NULL

说明:
两个整数数组没有同时出现的整数,输出NULL。

示例2

输入:
5,8,11,3,6,8,8,-1,11,2,11,11
11,2,11,8,6,8,8,-1,8,15,3,-9,11

输出:
1:-1,2,3,6
3:8,11

说明:
两个整数数组中同时出现的整数为-1、2、3、6、8、11,其中同时出现次数为1的整数为-1,2,3,6(升序排序),同时出现次数为3的整数为8,11(升序排序),先升序输出出现次数为1的整数,再升序输出出现次数为3的整数。

题解

这道题目属于**哈希表(Hash Table)排序(Sorting)**的结合应用。主要考察的是如何利用哈希表高效统计元素的出现次数,并根据条件进行筛选和排序。

思路

  1. 统计出现次数:首先,我们需要分别统计两个数组中每个整数的出现次数。可以使用哈希表来记录每个整数及其出现的次数。
  2. 找出共同出现的整数:遍历其中一个哈希表,检查每个整数是否在另一个哈希表中也存在。如果存在,则计算该整数在两个数组中出现次数的较小值(即共同出现次数)。
  3. 按共同出现次数分类:将共同出现的整数按照其共同出现次数进行分类,存储到一个新的哈希表中,键为共同出现次数,值为该次数下的整数列表。
  4. 排序和输出
    • 对共同出现次数进行升序排序。
    • 对每个共同出现次数下的整数列表进行升序排序。
    • 按照格式输出结果,如果没有任何共同出现的整数,则输出NULL

JavaScript

const rl = require('readline').createInterface({
    input: process.stdin,
    output: process.stdout,
});

var iter = rl[Symbol.asyncIterator]();

const readline = async () => (await iter.next()).value;

// 统计每个元素出现的次数
function counter(arr) {
    const cnt = new Map();
    for (let k of arr) {
        let v = cnt.get(k) || 0;
        cnt.set(k, v + 1);
    }

    return cnt;
}

(async () => {
    const arr1 = (await readline()).split(',').map(Number);
    const arr2 = (await readline()).split(',').map(Number);

    // 对两个数组统计计数
    const cnt1 = counter(arr1);
    const cnt2 = counter(arr2);

    // 记录同时存在的结果值 (key = 两个数组中最小出现的次数, value =[对应的数字...])
    const result = new Map();
    cnt1.forEach((v1, k) => {
        let cnt = Math.min(cnt2.get(k) || 0, v1);
        if (cnt > 0) {
            if (!result.has(cnt)) result.set(cnt, []);
            result.get(cnt).push(k);
        }
    });

    if (result.size === 0) {
        console.log('NULL');
    } else {
        let lst = [...result.entries()];
        // 根据出现次数从小到大排序
        lst.sort((a, b) => a[0] - b[0]);
        // 每行结果格式化输出
        for (let [cnt, nums] of lst) {
            nums.sort((a, b) => a - b);
            console.log(`${cnt}:${nums.join(',')}`);
        }
    }

    rl.close();
})();

整理题解不易, 如果有帮助到您,请给点个赞 ‍❤️‍ 和收藏 ⭐,让更多的人看到。🙏🙏🙏

好的,以下是关于华为OD2024 E猜数字题目的一种常见思路及解答解析: --- ### 猜数字题背景简介 这类题目通常属于交互式算法问题。例如:系统会随生成一个目标数字,用户需要通过一定的策略猜测出这个数字,并满足特定条件(如最小化猜测次数)。一般还会提供反馈制,比如告诉玩家“更大”、“更小”或“正确”。 假设此题的目标是从 `1` 到 `n` 的范围内猜出某个隐藏的整数。 #### 核心思想 - 二分查找法 由于每次可以得到明确的方向性提示(大了还是小了),因此最高效的解法是 **二分查找** 法。这种方法能够将搜索空间快速减半,从而达到最优的时间复杂度 \(O(\log n)\)。 ##### 实现步骤 1. 初始化两个边界值: ```python low = 1 high = n ``` 2. 循环判断直至找到目标数字为止: - 每次取中间位置作为当前猜测值: ```python mid = (low + high) // 2 ``` - 向测环境提交该猜测并获取返回结果。(如果是自动化评测,则模拟接收响应) 3. 更新区间范围: - 如果返回的是 "太大" -> 将上限调整至 `mid - 1` - 若回复为 "太小" -> 把下限设置成 `mid + 1` 4. 当最终锁定唯一可能性时即停止循环输出答案。 --- ### 示例代码 ```python def guessNumber(n): low, high = 1, n while low <= high: mid = (low + high) // 2 # 假设这里有一个函数api_guess(mid),用于询问服务器 result = api_guess(mid) if result == 'correct': # 找到正确的数值 return mid elif result == 'higher': high = mid - 1 # 目标较小,更新上界 else: # result == 'lower' low = mid + 1 # 目标较大,更新下界 # 注释:上述伪代码中的api_guess()应由实际比赛平台提供的接口替代。 ``` --- #### 注意事项 - 要特别留意输入数据规模以及时间限制等因素影响选择合适的数据结构算法优化; - 对于部分高级变种版本可能会加入额外约束条件(例如代价权衡等), 那就需要考虑动态规划或者其他进阶技巧处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

什码情况

你的鼓励就是我最大的动力。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值