华为OD机试 - 阿里巴巴找黄金宝箱(II)(Java & JS & Python)

【满分】【华为OD机试真题2023B卷 JAVA&JS】阿里巴巴找黄金宝箱(I) 阿里巴巴找黄金宝箱(I) 题目描述:一贫如洗的樵夫阿里巴巴在去砍柴的路上,无意中发现了强盗集团的藏宝地,藏宝地有编号从0~N的箱子,每个箱子上面贴有一个数字,箱子中可能有一个黄金宝箱。黄金宝箱满足排在它之前的所有箱子数字和等于排在它之后的所有箱子数字和;第一个箱子左边部分的数字和定义为0;最后一个宝箱右边部分的数字和定义为0。 请帮阿里巴巴找到黄金宝箱,输出第一个满足条件的黄金宝箱编号,如果不存在黄金宝箱,请返回- 阅读详情

题目描述

一贫如洗的樵夫阿里巴巴在去砍柴的路上,无意中发现了强盗集团的藏宝地,藏宝地有编号从0-N的箱子,每个箱子上面贴有箱子中藏有金币的数量。

从金币数量中选出一个数字集合,并销毁贴有这些数字的每个箱子,如果能销毁一半及以上的箱子,则返回这个数字集合的最小大小

输入描述

一个数字字串,数字之间使用逗号分隔,例如:6,6,6,6,3,3,3,1,1,5

字串中数字的个数为偶数,并且

  • 1 ≤ 字串中数字的个数 ≤ 100000
  • 1 ≤ 每个数字 ≤ 100000

输出描述
这个数字集合的最小大小,例如: 2

用例

输入1,1,1,1,3,3,3,6,6,8
输出2
说明

选择集合{1,8},销毁后的结果数组为[3,3,3,6,6],长度为5,长度为原数组的一半。

大小为 2 的可行集合还有{1,3},{1,6},{3,6}。
选择 {6,8} 集合是不可行的,它销后的结果数组为[1,1,1,1,3,3,3],新数组长度大于原数组的二分之一。

输入2,2,2,2
输出1
说明

我们只能选择集合{2},销毁后的结果数组为空。

题目解析

本题主要考察贪心思维。

本题中有几个数字的概念:

箱子上贴的数字

箱子中金币数量

箱子的个数

其中,箱子上贴的数字就是箱子中金币数量,这里我们可以将这两个概念合并为一个箱子的类别

箱子的类别(等价于箱子上贴的数字,等价于箱子中金币数量)

箱子的个数

我们需要统计 各个类别的出现次数。

然后,对这些类别按照出现次数进行降序排序,即第一个类别的箱子的出现次数最多。

本题想要销毁最多的箱子,但是又要尽可能保留最多类别,因此根据贪心原则,我们应该优先销毁出现次数最多的类别,这样就能保证销毁最少的类别,但是可以销毁更多的箱子,让销毁的箱子数量尽快达到总数的一半及以上。

我们最后返回销毁的类别的数量即可。

Java代码

import java.util.*;
import java.util.stream.Collectors;
 
public class Main {
  public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);
    int[] nums = Arrays.stream(sc.nextLine().split(",")).mapToInt(Integer::parseInt).toArray();
    System.out.println(getResult(nums));
  }
 
  public static int getResult(int[] nums) {
    // 箱子上贴的数字可以看出 类别
    // 统计每一个类别出现的次数,key是类别,value是类别出现次数
    HashMap<Integer, Integer> count = new HashMap<>();
 
    for (int num : nums) {
      count.put(num, count.getOrDefault(num, 0) + 1);
    }
 
    // half是箱子数量的一半,注意向上取整,因为比如箱子有7个,则销毁一半及以上的箱子数量至少是4个,而不是3个
    int half = (int) Math.ceil(nums.length / 2.0);
 
    // 按类别出现次数降序 类别
    List<Map.Entry<Integer, Integer>> collect =
        count.entrySet().stream()
            .sorted((a, b) -> b.getValue() - a.getValue())
            .collect(Collectors.toList());
 
    // remove记录销毁的箱子数量
    int remove = 0;
    // numCount记录销毁的类别数量
    int numCount = 0;
    // 贪心思维,想要销毁最多的箱子数,又要销毁的箱子的类别数最少,则应该尽可能销毁出现次数多的类别,因此前面对按照次数降序了类别
    for (Map.Entry<Integer, Integer> entry : collect) {
      remove += entry.getValue();
      numCount++;
      // 一旦达标,则返回销毁的类别数量
      if (remove >= half) {
        return numCount;
      }
    }
 
    return -1; // 走不到此行,仅用于代码健壮性
  }
}

JS代码

/* JavaScript Node ACM模式 控制台输入获取 */
const readline = require("readline");
 
const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
});
 
rl.on("line", (line) => {
  const nums = line.split(",").map(Number);
  console.log(getResult(nums));
});
 
function getResult(nums) {
  // 箱子上贴的数字可以看成 类别
  // 统计每一个类别出现的次数,key是类别,value是类别出现次数
  const count = {};
 
  for (let num of nums) {
    count[num] = (count[num] ?? 0) + 1;
  }
 
  // half是箱子数量的一半,注意向上取整,因为比如箱子有7个,则销毁一半及以上的箱子数量至少是4个,而不是3个
  const half = Math.ceil(nums.length / 2);
 
  // 按类别出现次数降序 类别
  const sortedEntery = Object.entries(count).sort((a, b) => b[1] - a[1]);
 
  // remove记录销毁的箱子数量
  let remove = 0;
  // numCount记录销毁的类别数量
  let numCount = 0;
 
  // 贪心思维,想要销毁最多的箱子数,又要销毁的箱子的类别数最少,则应该尽可能销毁出现次数多的类别,因此前面对按照次数降序了类别
  for (let entry of sortedEntery) {
    remove += entry[1];
    numCount++;
    // 一旦达标,则返回销毁的类别数量
    if (remove >= half) {
      return numCount;
    }
  }
 
  return -1; // 走不到此行,仅用于代码健壮性
}

Python代码

# 输入获取
import math
 
nums = list(map(int, input().split(",")))
 
 
# 算法入口
def getResult():
    # 箱子上贴的数字可以看成 类别
    # 统计每一个类别出现的次数,key是类别,value是类别出现次数
    count = {}
 
    for num in nums:
        count[num] = count.get(num, 0) + 1
 
    # half是箱子数量的一半,注意向上取整,因为比如箱子有7个,则销毁一半及以上的箱子数量至少是4个,而不是3个
    half = int(math.ceil(len(nums) / 2))
 
    # 按类别出现次数降序 类别
    entries = list(count.items())
    entries.sort(key=lambda x: -x[1])
 
    # remove记录销毁的箱子数量
    remove = 0
    # numCount记录销毁的类别数量
    numCount = 0
 
    # 贪心思维,想要销毁最多的箱子数,又要销毁的箱子的类别数最少,则应该尽可能销毁出现次数多的类别,因此前面对按照次数降序了类别
    for entry in entries:
        remove += entry[1]
        numCount += 1
        # 一旦达标,则返回销毁的类别数量
        if remove >= half:
            return numCount
 
    return -1  # 走不到此行,仅用于代码健壮性
 
 
# 算法调用
print(getResult())
【100分】【阿里巴巴找黄金宝箱(II)】 个数字字串,数字之间使用逗号分隔,例如: 6,6,6,6,3,3,3,1,1.5字串中数字的个数为偶数,一贫如洗的樵夫阿里巴巴在去砍柴的路上,无意中发现了强盗集团的藏宝地,藏宝地有编号从0~N的箱子,题目要求是找到一个数字集合,使得销毁这个集合中出现的数字的箱子数量至少是箱子总数的一半及以上。接下来,我们需要计算箱子数量的一半,并使用向上取整来保证销毁一半及以上的箱子。,每次将一个类别的箱子全部销毁,并将销毁的箱子数量和销毁的类别数量分别累加。从金币数量中选出一个数字集合,并销毁贴有这些数字的每个箱子, 阅读详情

相关推荐

【OD统一考试(B卷)考生抽中题】阿里巴巴找黄金宝箱(2),用 C++ 编码,速通

一贫如洗的樵夫阿里巴巴在去砍柴的路上,无意中发现了强盗集团的藏宝地,藏宝地有编号从0~N的箱子,每个箱子上面贴有箱子中藏有金币的数量。选择 {6,8} 集合是不可行的,它销毁后的结果数组为 [1,1,1,1,3,3,3],新数组长度大于原数组的二分之一。从金币数量中选出一个数字集合,并销毁贴有这些数字的每个箱子,如果能销毁一半及以上的箱子,则返回这个数字集合的最小大小。选择集合 {1,8},销毁后的结果数组为 [3,3,3,6,6],长度为 5,长度为原数组的一半。这个数字集合的最小大小,例如:2。

梦想橡皮擦,专栏100例写作模式先行者,现象级专栏 《Python 爬虫 100 例》作者、《滚雪球学 Python 专栏》原创者 1万+

【备战秋招】每日一题:2023.05-B卷-华为OD机试 - 阿里巴巴找黄金宝箱(III)

2023大厂笔试模拟练习网站(含题解)最近我们一直在将收集到的各种大厂笔试的解题思路还原成题目并制作数据,挂载到我们的OJ上,供大家学习交流,体会笔试难度。现已录入200+道互联网大厂模拟练习题,还在极速更新中。欢迎关注公众号“塔子哥学算法”获取最新消息。为了更好的阅读体检,可以查看OJ上的题解。进入提交链接,点击右边菜单栏的"查看塔子哥的题解"

m0_73659489的博客 1198

【华为OD机试真题】阿里巴巴找黄金宝箱(C++&Java&python)【2023(B卷)100分】

已支持(C++&Java&python)【2023(B卷)100分】

笑着的程序员的博客 728

华为OD机试真题——阿里巴巴找黄金宝箱(II)(2025A卷:100分)Java/python/JavaScript/C/C++/GO最佳实现

华为OD机试真题——阿里巴巴找黄金宝箱(II)(2025A卷:100分)Java/python/JavaScript/C/C++/GO最佳实现

专注分享技术、实用优质教程、资源 1306

2026华为OD机试(Python)真题【E卷+A卷+B卷+C卷+D卷】目录+在线OJ

华为OD机试真题题库【E卷+A卷+B卷+C卷+D卷】目录,Python实现。

MISAYAONE的博客 29万+

华为OD机试2025A卷 - 阿里巴巴找黄金宝箱II(Java & Python& JS & C++ & C )

一贫如洗的樵夫阿里巴巴在去砍柴的路上,无意中发现了强盗集团的藏宝地,藏宝地有编号从0-N的箱子,每个箱子上面贴有箱子中藏有金币的数量。

算法大师! 3512

【华为OD】D卷真题100分:阿里巴巴找黄金宝箱(II) C语言代码实现[思路+代码]

一贫如洗的樵夫阿里巴巴在去砍柴的路上,无意中发现了强盗集团的藏宝地,藏宝地有编号从0~N的箱子,每个箱子上面贴有箱子中藏有金币的数量。 从金币数量中选出一个数字集合,并销毁贴有这些数字的每个箱子,如果能销毁一半及以上的箱子,则返回这个数字集合的最小大小。 输入描述 一个数字字串,数字之间使用逗号分隔,例如: 6,6,6,6,3,3,3,1,1,5 字串中数字的个数为偶数,并且个数>=1,100000;每个数字>=1,100000; 输出描述这个数字集合的最小大小,例如:2

十年以上编程经验的干货分享 962

2026华为OD机试(JavaScript)真题【E卷+A卷+B卷+C卷+D卷】目录+在线OJ

华为OD机试真题题库【E卷+A卷+B卷+C卷+D卷】目录,JavaScript实现。

MISAYAONE的博客 8万+

【华为OD】D卷真题100分:阿里巴巴找黄金宝箱(II) C++代码实现[思路+代码]

一贫如洗的樵夫阿里巴巴在去砍柴的路上,无意中发现了强盗集团的藏宝地,藏宝地有编号从0~N的箱子,每个箱子上面贴有箱子中藏有金币的数量。 从金币数量中选出一个数字集合,并销毁贴有这些数字的每个箱子,如果能销毁一半及以上的箱子,则返回这个数字集合的最小大小。 输入描述 一个数字字串,数字之间使用逗号分隔,例如: 6,6,6,6,3,3,3,1,1,5 字串中数字的个数为偶数,并且个数>=1,100000;每个数字>=1,100000; 输出描述这个数字集合的最小大小,例如:2

十年以上编程经验的干货分享 891

2026华为OD机考新系统真题 + 双机位C卷 + 往年真题 - 题库目录分值说明 + 考点说明+在线OJ

2026年4月1日起,华为OD机试正式切换至新系统模式!采用力扣模式,无需自己写输入! 难度大幅度降低。正在备考华为OD机试的同学,优先刷新系统机试真题,可大幅提升通过率。 新系统考题考点与旧版一致,无需重新适应。本专栏所有算法题均配有详细思路解析,并提供C语言、JS、C++、Python、Go、Java多语言源码实现。订阅后私信即可开通专属OJ刷题权限,高效备考一次上岸!

算法大师! 45万+

【华为OD机试真题 2025B卷】313、阿里巴巴找黄金宝箱(II) | 机试真题+思路参考+代码解析(C++、Java、Py、C语言、JS)

题目描述 >一贫如洗的樵夫阿里巴巴在去砍柴的路上,无意中发现了强盗集团的藏宝地,藏宝地有编号从0~n 的箱子,每个箱子上面贴有箱子中藏有金币的数量。 从金币数量中选出一个数字集合,并销毁贴有这些数字的每个箱子,如果能销毁一半及以上的箱子,则返回这个数字集合的最小大小

KJ.JK 1445

【华为OD】D卷真题100分:阿里巴巴找黄金宝箱(II) python代码实现[思路+代码]

一贫如洗的樵夫阿里巴巴在去砍柴的路上,无意中发现了强盗集团的藏宝地,藏宝地有编号从0~N的箱子,每个箱子上面贴有箱子中藏有金币的数量。 从金币数量中选出一个数字集合,并销毁贴有这些数字的每个箱子,如果能销毁一半及以上的箱子,则返回这个数字集合的最小大小。 输入描述 一个数字字串,数字之间使用逗号分隔,例如: 6,6,6,6,3,3,3,1,1,5 字串中数字的个数为偶数,并且个数>=1,100000;每个数字>=1,100000; 输出描述这个数字集合的最小大小,例如:2

十年以上编程经验的干货分享 840

华为OD机试 新系统 双机位C卷 往年真题 机考题库(持续收录中)以及算法考点详解(Python/JS/C/C++)

刷的越多,抽中的概率越大,每一题都有详细的答题思路、详细的代码注释发现新题目,随时更新。

学Java,找哪吒 5万+

【华为OD】D卷真题100分:阿里巴巴找黄金宝箱(II) Java代码实现[思路+代码]

一贫如洗的樵夫阿里巴巴在去砍柴的路上,无意中发现了强盗集团的藏宝地,藏宝地有编号从0~N的箱子,每个箱子上面贴有箱子中藏有金币的数量。 从金币数量中选出一个数字集合,并销毁贴有这些数字的每个箱子,如果能销毁一半及以上的箱子,则返回这个数字集合的最小大小。 输入描述 一个数字字串,数字之间使用逗号分隔,例如: 6,6,6,6,3,3,3,1,1,5 字串中数字的个数为偶数,并且个数>=1,100000;每个数字>=1,100000; 输出描述这个数字集合的最小大小,例如:2

十年以上编程经验的干货分享 1248

华为OD机试 新系统 双机位C卷 真题题库目录|机考题库 + 算法考点详解

本文整理华为OD机试(机考) 新系统真题题库,提供高频考点精析与详细题目内容,提供C语言、Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解 和 在线OJ做题练习。华为OD机试新系统真题题库。

qq_45776114的博客 10万+

2026华为OD机试(JAVA&Go)真题【E卷+A卷+B卷+C卷+D卷】目录+在线OJ

华为OD机试真题题库【E卷+A卷+B卷+C卷+D卷】目录,Java实现。

MISAYAONE的博客 34万+

【华为OD机试真题 2025B卷】749、阿里巴巴找黄金宝箱(II) | 机试真题+思路参考+代码解析(C++、Java、Py、C语言、JS)

【华为OD机试真题 2025B卷】749、阿里巴巴找黄金宝箱(II) | 机试真题+思路参考+代码解析(C++、Java、Py、C语言、JS) 华为od机试,华为od机试真题,华为od机试E卷,华为odE卷,华为od机试真题E卷,华为OD,华为OD机试,华为OD机试真题,华为od机考,华为od机试D卷,华为od机试真题D卷,华为od手撕代码,华为od,华为od机试C卷,华为od e卷,华为2025e卷,od机试,2025E卷,华为OD机试E卷,什么是华为od,华为od介绍,全面了解华为od,2025华为o

KJ.JK 137

2026华为OD机试(C语言)真题【E卷+A卷+B卷+C卷+D卷】目录+在线OJ

华为OD机试真题题库【E卷+A卷+B卷+C卷+D卷】目录,C语言实现。

MISAYAONE的博客 11万+
上一篇: 华为OD机试 - 最小调整顺序次数、特异性双端队列(Java & JS & Python)
下一篇: 华为OD机试 - 五子棋迷(Java & JS & Python)
清水乐园
博客等级 码龄13年 175粉丝 398原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

打赏作者

清水乐园

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值