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:
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.
The solution can be broken down into the following steps:
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]
.
nums[i]
so that the next comparison uses the new value.
This greedy, single-pass approach guarantees minimal increments because at each step, we only increase as much as necessary.
Example: nums = [1, 1, 1]
Let's trace the steps:
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.[1, 2, 1]
, total operations: 1.nums[2] (1)
to nums[1] (2)
. 1 is not greater than 2, so increment nums[2]
to 3. This takes 2 operations.[1, 2, 3]
, total operations: 3.Brute-force approach:
O(n)
, where n
is the length of the array, since we iterate through the array once.O(1)
if we modify the array in-place, or O(n)
if we make a copy (not required in this case).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.
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;
};