Given an array arr[] where each element (arr[i]) represents the height of the tower. Find the nearest possible tower that is shorter than it for each tower. You can look left or right on both sides.
- If two smaller towers are at the same distance, pick the smallest tower.
- If two towers have the same height, we choose the one with a smaller index.
Examples:
Input: arr[] = {1, 3, 2}
Output: {-1, 0, 0}
Explanation:
- For 0th Index: no tower is smallest, so -1.
- For 1st Index: For 3, here 1 & 2 both are small & at the same distance, so we will pick 1 because it has the smallest value, so 0(Index)
- For 2nd Index : here 1 is smaller, so 0(Index) So the final output will be which consists Indexes are {-1, 0, 0}.
Input: arr[] = {4, 8, 3, 5, 3}
Output: {2, 2, -1, 2, -1}
Explanation:
- For 0th Index: here 3 is the smaller, so 2(Index)
- For 1st Index: For 8, here 4 & 3 both are small & at the same distance, so we will pick 3, so 2(Index)
- For the 2nd Index: no tower is smallest, so -1.
- For 3rd Index : For 5, here 3 & 3 both are small & at a same distance, so we will pick 3(2nd Index) because it smaller Index, so 2(Index)
- For 4th Index: no tower is smallest, so -1. So the final output will be which consist of Indexes {2, 2, -1, 2, -1}.
Approach: This can be solved with the following idea:
The idea is to use two stacks to find the nearest smaller tower on the left and on the right for each tower in the array. It first finds the nearest smaller tower on the left for each tower using a stack, then finds the nearest smaller tower on the right for each tower using another stack. Finally, we compare the nearest smaller towers on the left and on the right for each tower and choose the tower with the smaller height if there are two towers at the same distance.
Below are the steps involved in the implementation of the code:
- Initializes an array res of length n with -1, where n is the length of the input array arr. This array will store the index of the nearest smaller tower for each tower in the input array.
- Use a stack pre to find the index of the nearest smaller tower to the left of the current tower. For each tower, I in the input array, pop all the indices from pre until it finds an index whose corresponding tower has a smaller height than the current tower arr[i]. The index of this smaller tower is then stored in res[i]. Finally, the current index i is pushed onto pre.
- Similarly, create another stack for storing smaller elements on the right side of the current tower.
-
For each tower, i in the input array (in reverse order), pop all the indices from suf until it finds an index whose corresponding tower has a smaller height than the current tower arr[i].
- If the res[i] already contains an index (i.e., a smaller tower has already been found to the left of the current tower), then the algorithm compares the distance of the index found by suf to the current index i with the distance of the index stored in res[i] to i.
- If the distances are the same, then the algorithm chooses the tower with the smaller height; if the distances are different, then the algorithm chooses the tower that is closer to the current tower.
- If res[i] is not yet initialized (i.e., no smaller tower has been found to the left of the current tower), then the index found by suf is stored in res[i].
- Finally, the current index i is pushed onto suf.:
Below is the implementation of the above code:
// C++ code of the above approach #include <bits/stdc++.h> using namespace std;
// Function to find nearest smallest tower vector< int > nearestSmallerTower(vector< int >& arr)
{ int n = arr.size();
stack< int > pre, suf;
vector< int > res(n, -1);
// Make prefix stack
for ( int i = 0; i < n; i++) {
while (!pre.empty() && arr[pre.top()] >= arr[i]) {
pre.pop();
}
if (!pre.empty()) {
res[i] = pre.top();
}
pre.push(i);
}
// Make suffix stack
for ( int i = n - 1; i >= 0; i--) {
while (!suf.empty() && arr[suf.top()] >= arr[i]) {
suf.pop();
}
if (!suf.empty()) {
if (res[i] != -1) {
if ( abs (res[i] - i) == abs (suf.top() - i)) {
if (arr[res[i]] > arr[suf.top()])
res[i] = suf.top();
}
else if ( abs (res[i] - i)
> abs (suf.top() - i))
res[i] = suf.top();
}
else
res[i] = suf.top();
}
suf.push(i);
}
return res;
} // Driver code int main()
{ vector< int > arr = { 1, 3, 2 };
// Function call
vector< int > ans = nearestSmallerTower(arr);
for ( auto it : ans)
cout << it << " " ;
return 0;
} |
import java.util.*;
public class NearestSmallerTower {
public static List<Integer> nearestSmallerTower(List<Integer> arr) {
int n = arr.size();
Stack<Integer> pre = new Stack<>();
Stack<Integer> suf = new Stack<>();
List<Integer> res = new ArrayList<>(Collections.nCopies(n, - 1 ));
// Make prefix stack
for ( int i = 0 ; i < n; i++) {
while (!pre.isEmpty() && arr.get(pre.peek()) >= arr.get(i)) {
pre.pop();
}
if (!pre.isEmpty()) {
res.set(i, pre.peek());
}
pre.push(i);
}
// Make suffix stack
for ( int i = n - 1 ; i >= 0 ; i--) {
while (!suf.isEmpty() && arr.get(suf.peek()) >= arr.get(i)) {
suf.pop();
}
if (!suf.isEmpty()) {
if (res.get(i) != - 1 ) {
if (Math.abs(res.get(i) - i) == Math.abs(suf.peek() - i)) {
if (arr.get(res.get(i)) > arr.get(suf.peek())) {
res.set(i, suf.peek());
}
} else if (Math.abs(res.get(i) - i) > Math.abs(suf.peek() - i)) {
res.set(i, suf.peek());
}
} else {
res.set(i, suf.peek());
}
}
suf.push(i);
}
return res;
}
public static void main(String[] args) {
List<Integer> arr = Arrays.asList( 1 , 3 , 2 );
// Function call
List<Integer> ans = nearestSmallerTower(arr);
for ( int it : ans) {
System.out.print(it + " " );
}
}
} |
# Python code of the above approach # Function to find nearest smallest tower def nearest_smaller_tower(arr):
n = len (arr)
pre = [] # Stack for previous towers
suf = [] # Stack for next towers
res = [ - 1 ] * n # Initialize result array with -1
# Make prefix stack
for i in range (n):
while pre and arr[pre[ - 1 ]] > = arr[i]:
pre.pop()
if pre:
res[i] = pre[ - 1 ]
pre.append(i)
# Make suffix stack
for i in range (n - 1 , - 1 , - 1 ):
while suf and arr[suf[ - 1 ]] > = arr[i]:
suf.pop()
if suf:
if res[i] ! = - 1 :
if abs (res[i] - i) = = abs (suf[ - 1 ] - i):
if arr[res[i]] > arr[suf[ - 1 ]]:
res[i] = suf[ - 1 ]
elif abs (res[i] - i) > abs (suf[ - 1 ] - i):
res[i] = suf[ - 1 ]
else :
res[i] = suf[ - 1 ]
suf.append(i)
return res
# Driver code arr = [ 1 , 3 , 2 ]
# Function call ans = nearest_smaller_tower(arr)
for it in ans:
print (it, end = ' ' )
|
using System;
public class TowerIndices
{ // Method to find the indices of the smallest towers
public static int [] FindSmallestTowerIndices( int [] arr)
{
int n = arr.Length;
int [] result = new int [n];
for ( int i = 0; i < n; i++)
{
int closestSmaller = -1; // Index of the closest smaller tower
int minDistance = int .MaxValue; // Minimum distance to a smaller tower
// Iterate over previous towers to find the closest smaller tower
for ( int j = i - 1; j >= 0; j--)
{
if (arr[j] < arr[i])
{
int distance = i - j;
if (distance < minDistance)
{
minDistance = distance;
closestSmaller = j;
}
}
}
result[i] = closestSmaller;
}
return result;
}
public static void Main( string [] args)
{
int [] arr = { 1, 3, 2 };
int [] result = FindSmallestTowerIndices(arr);
// Print the result for arr1
Console.WriteLine( "{" + string .Join( ", " , result) + "}" );
}
} // This code is contributed by Vikram_Shirsat |
// Function to find nearest smallest tower function nearestSmallerTower(arr) {
let n = arr.length;
let pre = [];
let suf = [];
let res = new Array(n).fill(-1);
// Make prefix stack
for (let i = 0; i < n; i++) {
while (pre.length > 0 && arr[pre[pre.length - 1]] >= arr[i]) {
pre.pop();
}
if (pre.length > 0) {
res[i] = pre[pre.length - 1];
}
pre.push(i);
}
// Make suffix stack
for (let i = n - 1; i >= 0; i--) {
while (suf.length > 0 && arr[suf[suf.length - 1]] >= arr[i]) {
suf.pop();
}
if (suf.length > 0) {
if (res[i] != -1) {
if (Math.abs(res[i] - i) == Math.abs(suf[suf.length - 1] - i)) {
if (arr[res[i]] > arr[suf[suf.length - 1]]) {
res[i] = suf[suf.length - 1];
}
} else if (Math.abs(res[i] - i) > Math.abs(suf[suf.length - 1] - i)) {
res[i] = suf[suf.length - 1];
}
} else {
res[i] = suf[suf.length - 1];
}
}
suf.push(i);
}
return res;
} // Test case let arr = [1, 3, 2]; // Function call let ans = nearestSmallerTower(arr); for (let it of ans) {
console.log(it + " " );
} |
-1 0 0
Time Complexity: O(N+N)
Auxiliary Space: O(N+N+N)