华为OD机试之阿里巴巴找黄金宝箱(II)(Java源码)

阿里巴巴找黄金宝箱(II)

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

输入描述
一个数字字串,数字之间使用逗号分陌,例如: 6,6,6,6,3,3,3,1,1,5字串中数字的个数为偶数,并且个数>=1,<=100000:;每个数字>=1,<=100000;

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

输入 输出 说明
6,6,6,6,3,3,3,1,1,5 2 当集合内数字为6和3 时,可以销毁掉7个箱子,占一半以上了

解析

  1. 理解题意,这个题就是为了让你找一个集合,这个集合中每个数字出现次数之和占集合一半及以上。不可使用for循环,因为不知道会出现几个数字才能满足条件。看似简单,实则对于算法基础稍微差一些的人来说,可能会有点难搞。
  2. 这个题还是使用数位DP算法最为简单,不懂的可以参考我的博客 【算法】使用数位算法生成0至某个数之间的整数(for循环之外的另一种实现方式,蛮长见识的)
  3. 本示例采用map和List集合的方式进行解题。
    3.1 将每个数字及其出现的次数存入List,对该List进行排序。出现的次数越多,越靠前。因为需要集合的大小最小,所以只有可能集合中的数字出现最多,才有可能最小。
    3.2 遍历这个数组,从前往后依次取集合的键和值,做求和判断运算即可找出结果

示例代码

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;

public class T64 {
    
    
	public static void main(String[] args) {
    
    
		Scanner sc = new Scanner(System.in);
		String input = sc.nextLine();
		Map<Integer, Integer> map = new HashMap<Integer, Integer>();
		List<Integer> keyList = new ArrayList<>();
		Arrays.stream(input.split(",")).forEach(item -> {
    
    
			Integer key = Integer.parseInt(item);
			if (map.containsKey(key)) {
    
    
				map.put(key, map.get(key) + 1);
			} else {
    
    
				map.put(key, 1);
				keyList.add(key);
			}
		});
		int len = input.split(",").length;
		List<Map<Integer, Integer>> mapList = new ArrayList<>();
		for (Integer key1 : keyList) {
    
    
			Map<Integer, Integer> m = new HashMap<>();
			m.put(key1, map.get(key1));
			mapList.add(m);
		}
		mapList.sort(new Comparator<Map<Integer, Integer>>() {
    
    
			@Override
			public int compare(Map<Integer, Integer> o1, Map<Integer, Integer> o2) {
    
    
				Integer v1 = o1.get(o1.keySet().iterator().next());
				Integer v2 = o2.get(o2.keySet().iterator().next());
				if (v1 > v2)
					return -1;
				if (v1 < v2)
					return 1;
				return 0;
			}
		});
		int count = 0;
		int tempLen = 0;
		// System.out.println(mapList);
		while (tempLen < len / 2) {
    
    
			// System.out.println(mapList.get(count));
			tempLen += mapList.get(count).get(mapList.get(count).keySet().iterator().next());
			count++;
		}
		System.out.println(count);
	}
}

代码运行截图

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_33183456/article/details/131299526