Open In App

Finding nearest shortest tower in Array

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.

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:

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] * # 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 + " ");
}

Output
-1 0 0 







Time Complexity: O(N+N) 
Auxiliary Space: O(N+N+N)  


Article Tags :