数组insert_算法题——[leetcode1675]最小化数组差

Hard级别的新题:给定整数数组nums, 你每次可以对其中任意的数进行如下操作:

(1) 如果元素是奇数,则你可以把它乘以2

(2)如果元素是偶数,则你可以把它除以2

两种操作可以进行任意多次,变换后的数组的差定义为任意两个元素的差的最大值。求最小的数组差。

数据范围:2<=nums.size()<=100000, 1 <= nums[.]<=1000000000

例如: nums[] = {1, 2, 3, 4}答案是1, 因为我们可以把1乘以2, 把4除以2,数组变为{2, 2, 3, 2},差为1。

分析:求的是数组的最大值减去最小值的差的最小值。我们先把数组里奇数都乘以2,如此以后所有的数都是偶数,而且所有的数都只能进行操作(1)了,也只能减小了。

然后我们枚举最大值——用multiset或者堆。对于某个最大值,如果要使得数组差值尽可能小,最小值是不能减小的——显然我们希望最小值尽可能大,才能够接近最大值,所以我们就用当前最大值减最小值作为一个可行解。

如果最大值是偶数,则把它除以2,再扔回去——注意下次取最大值可能已经变了,因为mutliset里始终存放着全部数组元素。如果最大值是奇数,我们就可以停止了,因为最大值已经不能再减小了……

代码:

class Solution {public:    int minimumDeviation(vector<int>& nums) {        multiset<int> s;        for (int x : nums) {            s.insert((x & 1) ? (x << 1) : x);        }        int r = *s.rbegin() - *s.begin();        for (;;) {            auto t = s.end();            const int x = *(--t);            r = min(r, x - *s.begin());            if (x & 1) break;            s.erase(t);            s.insert(x >> 1);        }        return r;    }};

7dcd4744a9f1f6a786797dfa4b1b9d38.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值