Reputation: 857
I am solving a question "Steps to Make Array Non-decreasing" on LeetCode here. Question is:
You are given a 0-indexed integer array nums. In one step, remove all elements nums[i] where nums[i - 1] > nums[i] for all 0 < i < nums.length. Return the number of steps performed until nums becomes a non-decreasing array.
Input: nums = [5,3,4,4,7,3,6,11,8,5,11]
Output: 3
During the contest I got the intuition to solve it using a monotonic stack. I tried to solve it by keeping track of the next greater element (nge
) and previous greater element (pge
) for each element as below:
class Solution {
public:
int totalSteps(vector<int>& nums) {
int n=nums.size();
vector<int> nge(n), pge(n);
stack<int> stk, stk2;
for(int i=n-1; i>=0; i--) {
while(stk.size() && nums[stk.top()]<nums[i]) stk.pop();
nge[i]=stk.size() ? stk.top() : n;
stk.push(i);
}
int res=0;
for(int i=0; i<nums.size(); i++) {
res=max(res, nge[i]-i-1);
}
for(int i=0; i<n; i++) {
while(stk2.size() && nums[stk2.top()]<nums[i]) stk2.pop();
pge[i]=stk2.size() ? stk2.top() : -1;
stk2.push(i);
}
int ans=0;
for(int i=0; i<nums.size(); i++) {
ans=max(ans, i-pge[i]);
}
return min(res,ans);
}
};
However it continues to yield wrong answers. Any tips on how I could solve it?
Thanks!
Upvotes: 2
Views: 581
Reputation: 2953
I would go for a simpler algorithm like the one suggested by John Bayko. But, to make it fun, when thinking about algorithms I usually try to find the most appropriate standard library tools to compose them. So, here's how I might start with a short function to find the next iterator in nums to copy from, given a "current" iterator:
#include <algorithm>
#include <functional>
#include <ranges>
int totalSteps(std::vector<int>& nums) {
namespace rng = std::ranges;
auto nextOne = [&nums](auto current) {
return rng::adjacent_find(current, nums.end(), rng::greater{});
};
// ...
}
Is this suggestive enough?
Upvotes: 0