阿里笔试模拟题-74.钱庄

概述:
钱庄每天能够收到很多散钱,第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();
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值