3542. 将所有元素变为 0 的最少操作次数
给你一个大小为 n 的 非负 整数数组 nums 。你的任务是对该数组执行若干次(可能为 0 次)操作,使得 所有 元素都变为 0。
在一次操作中,你可以选择一个子数组 [i, j](其中 0 <= i <= j < n),将该子数组中所有 最小的非负整数 的设为 0。
返回使整个数组变为 0 所需的最少操作次数。
一个 子数组 是数组中的一段连续元素。
输入: nums = [0,2]
输出: 1
解释:
- 选择子数组
[1,1](即[2]),其中最小的非负整数是 2。将所有 2 设为 0,结果为[0,0]。 - 因此,所需的最少操作次数为 1。
输入: nums = [1,2,1,2,1,2]
输出: 4
解释:
- 选择子数组
[0,5](即[1,2,1,2,1,2]),最小非负整数是 1。将所有 1 设为 0,结果为[0,2,0,2,0,2]。 - 选择子数组
[1,1](即[2]),将 2 设为 0,结果为[0,0,0,2,0,2]。 - 选择子数组
[3,3](即[2]),将 2 设为 0,结果为[0,0,0,0,0,2]。 - 选择子数组
[5,5](即[2]),将 2 设为 0,结果为[0,0,0,0,0,0]。 - 因此,最少操作次数为 4。
根据示例我们可知,最小操作次数只与初始排布有关。应当尽量符合:
1.每次操作尽可能选更长的子数组
2.遇到0即需要进行分割
3.每次操作将当前最小值设置为0.
4.合并2+3:分割操作与分布单调性有关系。
1,1,2,2:两次操作
1,2,1,2 :三次操作
每次递增时,说明有新的值需要操作。出现递减时则应当c
根本原因是出现了递减分布。每次递减出现时应当重置单调栈(当前操作必定无法与之前可能的等价情况一起处理)。
class Solution {
public:int minOperations(vector<int>& nums) {vector<int>s;int res=0;for(int a:nums){//维护单调栈,确保递减时重置状态while (!s.empty() && a<s.back()) {s.pop_back();}if(a==0)continue;//初始时+1//忽略等价情况,同时确保递增即正常操作+1if(s.empty()||a>s.back()){++res;s.push_back(a);}}return res;}
};