LeetCode · Daily Question · 2208. The minimum number of operations to halve an array · Priority Queue

Author: Xiao Xun
Link: https://leetcode.cn/problems/minimum-operations-to-halve-array-sum/solutions/2357852/you-xian-dui-lie-zhu-shi-chao-ji-xiang- x-805n/
Source: The copyright of LeetCode
belongs to the author. For commercial reprint, please contact the author for authorization, for non-commercial reprint, please indicate the source.

topic

 

example

 

train of thought

Title -> Given an array, each operation can halve the value of any element, and return the minimum number of operations so that the sum of the elements of the array is half of the sum of the original array.

Greedy thinking, to make the number of operations as small as possible, then the maximum value must be selected for each reduction, so as to maximize the benefits of each step.

So how can we choose the maximum value every time?

  • The meaning of the question only requires the number of operations to be returned, and does not care about the contents of the array, so the array can be sorted, and the maximum value can be obtained only by taking the boundary each time.

After each element is halved, sort the array and repeat the above operation.

In fact, at this point, the overall idea has been determined, but different sorting algorithms have different time complexity, we need to choose a sort with small time complexity, and we only change the size of the topmost element each time, and the other elements are still in order , then it is very good to use heap sorting, which is the priority queue.

Code comments are super detailed

the code


// 堆排序:(最大堆,有序区)。从堆顶把根卸出来放在有序区之前,再恢复堆。
void max_heapify(float arr[], int start, int end) {
	//建立父节点指标和子节点指标
	int dad = start;
	int son = dad * 2 + 1;
	while (son <= end) { //若子节点在范围内才做比较
		if (son + 1 <= end && arr[son] < arr[son + 1]) //先比较两个子节点指标,选择最大的
			son++;
		if (arr[dad] >= arr[son]) //如果父节点大于子节点代表调整完成,直接跳出函数
			return;
		else { //否则交换父子内容再继续子节点与孙节点比较
			float temp = arr[dad];
            arr[dad] = arr[son];
            arr[son] = temp;
			dad = son;
			son = dad * 2 + 1;
		}
	}
}
int halveArray(int* nums, int numsSize){
    double sum = 0;
    float num[numsSize];
    for (int i = 0; i < numsSize; ++i) {//累和并初始化堆
        sum += nums[i];
        num[i] = nums[i];
    }
    for (int i = numsSize / 2 - 1; i >= 0; i--)//调整堆
        //调整每一个父节点下的子节点大小
		max_heapify(num, i, numsSize - 1);
    double temp = sum;
    int count = 0;
    while (sum < temp * 2) {//枚举操作数
        max_heapify(num, 0, numsSize-1);//调整和取数没有先后顺序,都可以
        num[0] /= 2;//取最大值操作
        temp -= num[0];
        ++count;
    }
    return count;
}

作者:小迅
链接:https://leetcode.cn/problems/minimum-operations-to-halve-array-sum/solutions/2357852/you-xian-dui-lie-zhu-shi-chao-ji-xiang-x-805n/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

Guess you like

Origin blog.csdn.net/m0_64560763/article/details/131912698