编程题——手套

分析:我们先不考虑 拿到的手套只数 ,

①最 粗暴 的拿法就是把全部手套都拿出来。此时数量为 左手手套总数 + 右手手套总数

②思考 进一步的优化方式, 把一只手的手套全部拿出来,另一只手的手套拿一只,必定可以组成一双。此时数量为 min(左手手套总数,右手手套总数)+ 1 。

③能不能再进一步优化呢? 可以!我们统计出 一只手的手套总数count 数量最少的某种颜色的手套数min。我们再这一堆里取 count-min+1 只手套,也可以确保拿到了所有颜色的手套最少一只。

④前边的思考看似非常爽,但是这会带来一个致命的BUG,如果只拿一直手套的那边对应的手套数为0,那我们依旧不能凑成一对。那怎么办呢?看来这道题的坑就在一于这个0,因此我们想办法消除这个。

终极解法:当一边一种颜色手套数为0时,就把另一只手相同颜色的手套全拿出来,使两边不会出现一种颜色你有我没有的情况。我们只需要考虑剩下的颜色就好了,就可以用上边第③步的方法来做。

代码如下

class Gloves {
public:
    int findMinimum(int n, vector<int> left, vector<int> right) {
        int count = 0; //左右手拿到的手套总数
        int left_count = 0,right_count = 0; //左右手的手套总数
        int left_min = INT_MAX,right_min = INT_MAX;//分别是左右手数量最少的某种颜色的数量。
        
        for(int i = 0;i < n;++i)
        {
            if(left[i]==0)
            {
                //左手没有这个颜色, 就从右手的手套里把对应的数量拿出来。因为颜色看不见,所有拿的可能是这种颜色,也可能是其他颜色
                //但其实并不影响结果: 如果拿的是该种颜色,那当然一点毛病没有。
                //                 即使拿到的不是该种颜色,我们可以把那几个“漏网之鱼”统计给拿出来的那写些颜色里。
                //                 因为我们本来就是要把所有颜色都拿出来的,所以并不影响。
                count+=right[i];  
            }
            else if(right[i]==0)
            {
                count+=left[i];
            }
            else
            {
                //走到这里时,就是排除了有0的情况了。
                left_count+=left[i];
                right_count+=right[i];
                left_min=min(left_min,left[i]);
                right_min = min(right_min,right[i]);
            }
        }
        //需要的数据都统计完毕
        //   去0拿出来的数量  保证拿出一只手的手套全部颜色至少一个,                    另一边随便拿一只
        return count + min(left_count - left_min + 1,right_count - right_min + 1) + 1;
    }
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值