You are given an array of integers arr
. Your task is to replace every element in the array with the greatest element among the elements to its right. For the last element, replace it with -1
because there is no element to its right.
i
(except the last), set arr[i]
to the maximum value among arr[i+1], arr[i+2], ..., arr[n-1]
.
arr[n-1]
, set it to -1
.
Constraints:
arr.length
≤ 104arr[i]
≤ 105At first glance, the problem seems to require examining all elements to the right of each index to find the maximum. This would mean, for each element, running a loop through the rest of the array, which would be slow for large arrays.
However, we notice that as we move from right to left, we can keep track of the maximum value we've seen so far. This way, instead of repeatedly scanning the right part of the array for every element, we can update the maximum in constant time and fill the array efficiently.
This approach is much faster and uses only a small amount of extra space (just a variable to store the current maximum).
max_so_far
, to -1
. This will hold the greatest value to the right as we iterate.
max_so_far
after replacement).max_so_far
.max_so_far
to be the maximum of its current value and the value from the temporary variable.This method efficiently replaces each element with the greatest element to its right in a single pass, and only uses constant extra space.
Let's walk through an example with arr = [17, 18, 5, 4, 6, 1]
:
max_so_far = -1
.
-1
, update max_so_far = max(-1, 1) = 1
. [17, 18, 5, 4, 6, -1]
1
, update max_so_far = max(1, 6) = 6
. [17, 18, 5, 4, 1, -1]
6
, update max_so_far = max(6, 4) = 6
. [17, 18, 5, 6, 1, -1]
6
, update max_so_far = max(6, 5) = 6
. [17, 18, 6, 6, 1, -1]
6
, update max_so_far = max(6, 18) = 18
. [17, 6, 6, 6, 1, -1]
18
, update max_so_far = max(18, 17) = 18
. [18, 6, 6, 6, 1, -1]
Final output: [18, 6, 6, 6, 1, -1]
class Solution:
def replaceElements(self, arr):
max_so_far = -1
for i in range(len(arr) - 1, -1, -1):
current = arr[i]
arr[i] = max_so_far
max_so_far = max(max_so_far, current)
return arr
class Solution {
public:
vector<int> replaceElements(vector<int>& arr) {
int max_so_far = -1;
for (int i = arr.size() - 1; i >= 0; --i) {
int current = arr[i];
arr[i] = max_so_far;
max_so_far = max(max_so_far, current);
}
return arr;
}
};
class Solution {
public int[] replaceElements(int[] arr) {
int maxSoFar = -1;
for (int i = arr.length - 1; i >= 0; i--) {
int current = arr[i];
arr[i] = maxSoFar;
maxSoFar = Math.max(maxSoFar, current);
}
return arr;
}
}
var replaceElements = function(arr) {
let maxSoFar = -1;
for (let i = arr.length - 1; i >= 0; i--) {
let current = arr[i];
arr[i] = maxSoFar;
maxSoFar = Math.max(maxSoFar, current);
}
return arr;
};
The optimized approach is efficient and suitable even for large arrays.
The key insight in this problem is to realize that you can efficiently compute the greatest element to the right by traversing the array from the end, updating a running maximum. This approach avoids redundant work and achieves O(n) time with O(1) extra space, making it both simple and elegant.