阿里巴巴找黄金宝箱(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个箱子,占一半以上了 |
解析
- 理解题意,这个题就是为了让你找一个集合,这个集合中每个数字出现次数之和占集合一半及以上。不可使用for循环,因为不知道会出现几个数字才能满足条件。看似简单,实则对于算法基础稍微差一些的人来说,可能会有点难搞。
- 这个题还是使用数位DP算法最为简单,不懂的可以参考我的博客 【算法】使用数位算法生成0至某个数之间的整数(for循环之外的另一种实现方式,蛮长见识的)
- 本示例采用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);
}
}
代码运行截图