概述:
钱庄每天能够收到很多散钱,第i个散钱的值2wi。为了便于管理,钱庄每天都会向中央银行申请兑换钱币,假设钱庄有一些散钱使得2k1+2k2+…+2km=2^x(x为非负整数),那么就可以将这些散钱兑换成一个大钱币,问在钱庄收到的这些散钱最终最少能变成几个钱币。
输入一个整数n,表示一共有n个钱币(1 <= n <= 106);再输入n个整数wi,表示有价值2wi(0 <= wi <= 10^6)的钱币。
输出兑换后最少的钱币数
示例1
输入:
4
[1, 1, 2, 3]
输出:
1
注意
21+21+22+23=2^4,因此兑换后最少为一个钱币
题目地址
74.钱庄
题目解题方法有文档解释,文档下载地址为以下
程序员面试宝典
但是官方只有解题思路,没有具体代码,所以这边我就附上我的解题代码,具体思路可以参照上面的解释,不一定完全一样,但是相似。
public int solution(int n, int[] m) {
HashMap<Integer,Integer> map = new HashMap<Integer,Integer>();
int min = Integer.MAX_VALUE;
int max = Integer.MIN_VALUE;
for(int i=0;i<n;i++){
map.put(m[i], map.getOrDefault(m[i], 0)+1);
min = Math.min(min, m[i]);
max = Math.max(max,m[i]);
}
int nums = 0;
for(int i=min;i<max-1;i++){
nums = map.getOrDefault(i, 0);
if(nums%2==0){
map.remove(i);
} else {
map.put(i, 1);
}
if((map.getOrDefault(i+1, 0)+nums/2)>0){
map.put(i+1, map.getOrDefault(i+1, 0)+nums/2);
}
}
while(map.getOrDefault(max, 0) != 0){
nums = map.getOrDefault(max, 0);
if(nums%2==0){
map.remove(max);
} else {
map.put(max, 1);
}
if((nums/2)>0){
map.put(max+1, nums/2);
}
max = max+1;
}
return map.size();
}