2023-07-25 LeetCode每日一题(将数组和减半的最少操作次数)

2023-07-25每日一题

一、题目编号

2208. 将数组和减半的最少操作次数

二、题目链接

点击跳转到题目位置

三、题目描述

给你一个正整数数组 nums 。每一次操作中,你可以从 nums 中选择 任意 一个数并将它减小到 恰好 一半。(注意,在后续操作中你可以对减半过的数继续执行操作)

请你返回将 nums 数组和 至少 减少一半的 最少 操作数。

示例1:
2023-07-25 LeetCode每日一题(将数组和减半的最少操作次数)_第1张图片
示例2:
2023-07-25 LeetCode每日一题(将数组和减半的最少操作次数)_第2张图片
提示:

  • 1 <= nums.length <= 105
  • 1 <= nums[i] <= 107

四、解题代码

class Solution {
    priority_queue<float, vector<float>, less<float>> q;
public:
    int halveArray(vector<int>& nums) {
        int n = nums.size();
        double sum = 0;
        for(int i = 0; i < n; ++i){
            q.push(nums[i]);
            sum += nums[i];
        }
        double target = (double)sum / 2;
        int res = 0;
        while(sum > target){
            float max_num = q.top();
            float num = max_num / 2;
            sum -= num;
            q.pop();
            q.push(num);
            ++res;
        }
    return res;
    }
};

五、解题思路

(1) 使用优先队列来解决该问题。首先我们求出数组中所有数字之和,因为数字最大是107 * 105,所以用double类型。后面除了数字小点的用float类型就够了,其余都使用double类型。

(2) 我们的目标是将和至少减少到最开始的一半,而且我们可以将存在的任何一个数字减少到一半,那我们要减少的更多,那么就每次减少最大的数字即可,这是贪心的思想。

(3) 我们如何得到最大的数字呢,自然考虑到优先队列,建立大根堆,这样队首的元素就是最大值。

(4)直到元素之和小于等于原来值的一半退出循环,将记录的次数输出即可。

你可能感兴趣的:(LeetCode每日一题,leetcode,算法,数据结构)