Want Help Cracking FAANG?

(Then click this)

×
Back to Question Bank

1827. Minimum Operations to Make the Array Increasing - Leetcode Solution

Problem Description

You are given an array of integers nums. Your task is to determine the minimum number of operations required to make the array strictly increasing.
In one operation, you can increment any element of the array by 1.
The result should be the minimum total number of increments needed so that for every valid index i (where 1 <= i < nums.length), nums[i] > nums[i-1] holds.
Constraints:

  • Each operation increments only one element by 1.
  • There is always at least one valid solution.
  • All elements must be strictly increasing after the operations.

Thought Process

When approaching this problem, the most direct way is to look at each pair of consecutive elements in the array. If the current element is not greater than the previous one, it must be increased.
A brute-force approach would be to consider all possible ways to increment elements, but this quickly becomes inefficient. Instead, we realize that for each position, if nums[i] is less than or equal to nums[i-1], we must increase nums[i] to be exactly nums[i-1] + 1. This ensures the minimal number of operations at each step and keeps the array as small as possible, which minimizes the total number of operations.
The main insight is that we can process the array in a single pass, always making the minimal increment needed at each step.

Solution Approach

The solution can be broken down into the following steps:

  1. Initialize a counter: Start with a variable to keep track of the total number of operations needed.
  2. Iterate through the array: For each element from the second element onward, compare it to the previous element.
  3. Check for strictly increasing condition: If nums[i] is less than or equal to nums[i-1], calculate the amount needed to make nums[i] just greater than nums[i-1].
  4. Increment and update: Add the required increment to the counter and update nums[i] so that the next comparison uses the new value.
  5. Return the result: After processing all elements, return the counter as the answer.

This greedy, single-pass approach guarantees minimal increments because at each step, we only increase as much as necessary.

Example Walkthrough

Example: nums = [1, 1, 1]
Let's trace the steps:

  • Step 1: Compare nums[1] (1) to nums[0] (1). Since 1 is not greater than 1, we must increment nums[1] to 2. This takes 1 operation.
  • Array becomes: [1, 2, 1], total operations: 1.
  • Step 2: Compare nums[2] (1) to nums[1] (2). 1 is not greater than 2, so increment nums[2] to 3. This takes 2 operations.
  • Array becomes: [1, 2, 3], total operations: 3.
  • Now the array is strictly increasing: 1 < 2 < 3.
Result: 3 operations are needed.

Time and Space Complexity

Brute-force approach:

  • Would involve trying all possible increments, leading to an exponential time complexity, which is not feasible for large arrays.
Optimized approach (greedy, single pass):
  • Time Complexity: O(n), where n is the length of the array, since we iterate through the array once.
  • Space Complexity: O(1) if we modify the array in-place, or O(n) if we make a copy (not required in this case).
The optimized approach is efficient for even large input sizes.

Summary

To make an array strictly increasing with the minimum number of increment operations, we process the array from left to right, and at each step, ensure that each element is greater than the previous one by incrementing only as much as necessary. This greedy approach is both simple and optimal, requiring only a single pass and constant extra space.

Code Implementation

class Solution:
    def minOperations(self, nums):
        operations = 0
        for i in range(1, len(nums)):
            if nums[i] <= nums[i-1]:
                increment = nums[i-1] - nums[i] + 1
                operations += increment
                nums[i] = nums[i-1] + 1
        return operations
      
class Solution {
public:
    int minOperations(vector<int>& nums) {
        int operations = 0;
        for (int i = 1; i < nums.size(); ++i) {
            if (nums[i] <= nums[i-1]) {
                int increment = nums[i-1] - nums[i] + 1;
                operations += increment;
                nums[i] = nums[i-1] + 1;
            }
        }
        return operations;
    }
};
      
class Solution {
    public int minOperations(int[] nums) {
        int operations = 0;
        for (int i = 1; i < nums.length; i++) {
            if (nums[i] <= nums[i-1]) {
                int increment = nums[i-1] - nums[i] + 1;
                operations += increment;
                nums[i] = nums[i-1] + 1;
            }
        }
        return operations;
    }
}
      
var minOperations = function(nums) {
    let operations = 0;
    for (let i = 1; i < nums.length; i++) {
        if (nums[i] <= nums[i - 1]) {
            let increment = nums[i - 1] - nums[i] + 1;
            operations += increment;
            nums[i] = nums[i - 1] + 1;
        }
    }
    return operations;
};