Cover image for leetcode每日一题 P3542 将所有元素变为 0 的最少操作次数

leetcode每日一题 P3542 将所有元素变为 0 的最少操作次数

字数 515
阅读
访客

时间轴

时间轴

2025-11-10

init

单调栈

题目:

滑动窗口 TLE

用滑动窗口模拟会 TLE

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
#include <vector>#include <climits>using std::vector;class Solution {    public:	void ops(vector<int> &nums, int start, int end)	{		int i;		int min = INT_MAX;		for (i = start; i < end; i++) {			if (nums[i] < min) {				min = nums[i];			}		}		for (i = start; i < end; i++) {			if (nums[i] == min) {				nums[i] = 0;			}		}	}	int minOperations(vector<int> &nums)	{		// 滑动窗口		int left = 0, right = 0;		int n = nums.size();		int res = 0;		while (left < n) {			while (left < n && nums[left] == 0) {				left++;			}			right = left;			while (right < n && nums[right] > 0) {				right++;			}			// [left, right)			if (left == right && left == n) {				break;			}			ops(nums, left, right);			res++;			//left = right;		}		return res;	}};int main(){	vector<int> nums = { 1, 2, 1, 2, 1, 2 };	Solution S;	S.minOperations(nums);}

单调栈

正确做法是单调栈:

  • 规律一:把若干相同的最小值同时变为 0,可以节省操作次数。
  • 规律二:如果两个相同的数之间有更小的数,则他们一定不同一起被变为 0。

我们遍历数组,维护一个单调递增栈,表示当前递增的非零元素序列

  • 对于每个元素 a,如果栈顶元素大于 a,根据规律二,栈顶元素不可能和之后的元素一起操作,需要弹出栈顶。
  • 如果 a 已经为 0,跳过,因为已经不需要操作。
  • 如果栈为空或栈顶元素小于 a,说明我们需要新的一次操作来覆盖 a,并把它加入栈,并把操作次数加一。
12345678910111213141516171819202122232425
#include <stack>#include <vector>using std::vector;using std::stack;class Solution {    public:	int minOperations(vector<int> &nums)	{		stack<int> s;		int res = 0;		for (int a : nums) {			while (!s.empty() && s.top() > a) {				s.pop();			}			if (a == 0)				continue;			if (s.empty() || s.top() < a) {				res++;				s.push(a);			}		}		return res;	}};
评论加载中…