Advertisement

Steps to Make Array Non-decreasing - LeetCode 2289 Solution

Steps to Make Array Non-decreasing - Complete Solution Guide

Steps to Make Array Non-decreasing is LeetCode problem 2289, a Medium level challenge. This complete guide provides step-by-step explanations, multiple solution approaches, and optimized code in python3, java, cpp, c.

Problem Statement

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 . Example 1: Input: nums = [5,3,4,4,7,3,6,11,8,5,11] Output: 3 Explanation: The following are the steps performed: - Step 1: [5, 3 ,4,4,7, 3 ,6,11, 8 , 5 ,11] becomes [5,4,4,7,6,11,11] - Step 2: [5, 4 ,4,7, 6 ,11,11] becomes [5,4,7,11,11] - Step 3: [5, 4 ,7,11,11] becomes [5

Detailed Explanation

The problem requires us to determine the number of steps needed to transform a given array `nums` into a non-decreasing array. In each step, we remove all elements `nums[i]` where `nums[i-1] > nums[i]`. We repeat this process until the array becomes non-decreasing, and the output is the number of steps taken.

Solution Approach

The provided solution uses a monotonic stack and dynamic programming to efficiently calculate the number of steps. The stack stores indices of elements that could potentially be greater than the next element (violating the non-decreasing property). The `dp` array stores the number of steps each element has to wait before becoming part of a non-decreasing sequence. The algorithm iterates through the input array, maintaining the stack's monotonicity. When an element is encountered that is greater than or equal to the top of the stack, the elements that are smaller than it are popped, updating the current element's `dp` value based on the popped elements' `dp` values. Finally, the maximum `dp` value is the answer.

Step-by-Step Algorithm

  1. Step 1: Initialize an empty stack to store indices and a `dp` array of the same size as the input `nums` array, filled with zeros. Also, initialize `ans = 0` to store the final result.
  2. Step 2: Iterate through the `nums` array from left to right.
  3. Step 3: For each element `nums[i]`, initialize `cur_steps = 0`.
  4. Step 4: While the stack is not empty and `nums[stack[-1]] <= nums[i]`, pop the top element from the stack and update `cur_steps` as `max(cur_steps, dp[popped_index])`.
  5. Step 5: If the stack is not empty after popping elements, it means there's an element `nums[stack[-1]] > nums[i]` to the left. Therefore set `dp[i] = cur_steps + 1`.
  6. Step 6: Push the current index `i` onto the stack.
  7. Step 7: Update the `ans` with the maximum `dp` value seen so far: `ans = max(ans, dp[i])`.
  8. Step 8: After iterating through all elements, return `ans`.

Key Insights

  • Insight 1: The core idea is to identify and remove elements that violate the non-decreasing property at each step. The number of steps is determined by the element that requires the maximum number of removals before it is no longer violating the condition.
  • Insight 2: A monotonic stack is the most suitable data structure to efficiently track potential violating elements and determine the removal steps required for each element.
  • Insight 3: Dynamic programming (DP) helps in storing the number of steps required to remove an element, avoiding redundant calculations.

Complexity Analysis

Time Complexity: O(n)

Space Complexity: O(n)

Topics

This problem involves: Array, Linked List, Stack, Monotonic Stack.

Companies

Asked at: Morgan Stanley.