Maximum people a person can see while standing in a line in both direction
Given an array height[] which represents the height of N people standing in a line. A person i can see a person j if height[j] < height[i] and there is no person k standing in between them such that height[k] ≥ height[i]. Find the maximum number of people a person can see.
Note: A person can see any other person irrespective of whether they are standing in his front or back.
Examples:
Input: heights[] = {6, 2, 5, 4, 5, 1, 6}.
Output: 6
Explanation:
Person 1 (height = 6) can see five other people at following positions (2, 3, 4, 5. 6) in addition to himself, i.e. total 6.
Person 2 (height: 2) can see only himself.
Person 3 (height = 5) is able to see people 2nd, 3rd, and 4th person.
Only Person 4 (height = 4) can see himself.
Person 5 (height = 5) can see people 4th, 5th, and 6th.
Person 6 (height =1) can only see himself.
Person 7 (height = 6) can see 2nd, 3rd, 4th, 5th, 6th, and 7th people.
A maximum of six people can be seen by Person 1, 7th
Input: heights[] = {1, 3, 6, 4 }
Output: 3
Naive Approach: A simple solution is to iterate through the given array and for every idx in the row:
- Maintain a left pointer (leftptr) which points to idx-1 and a right pointer (rightptr) which points to idx+1.
- Move the left pointer in the left direction until you find a person whose height is greater than or equal to height[idx].
- Move the right pointer in the right direction until you find a person whose height is greater than or equal to the height [idx].
- The difference between the indices of the right and left pointer gives us the number of people the ith person can see and update the Ans as max(Ans, rightptr – leftptr-1).
Below is the implementation of the above idea.
C++
// C++ code to implement the above approach #include <bits/stdc++.h> using namespace std; // Function to find the leftmost index // of the person whose height is // greater the height of person idx. int leftindex(vector< int > heights, int idx, int n) { int h = heights[idx]; for ( int i = idx - 1; i >= 0; i--) { // If height of person i is // greater than or equal to // current person of height h // then the current person(idx) // cannot see him if (heights[i] >= h) return i; } // If a person can see all other people // who are standing on his left return -1; } // Function to find the rightmost index // of the person whose height is // greater the height of person idx. int rightindex(vector< int > heights, int idx, int n) { int h = heights[idx]; for ( int i = idx + 1; i < n; i++) { // If height of person i is // greater than or equal to // current person of height h // then the current person(idx) // cannot see him if (heights[i] >= h) return i; } // If a person can see all other people // who are standing on his right return n; } // Function to find maximum number of people // a person can see int max_people(vector< int > heights, int n) { // Ans stores the maximum of people // a person can see int ans = 0; for ( int i = 0; i < n; i++) { // Leftptr stores the leftmost index // of the person which // the current person cannot see int leftptr = leftindex(heights, i, n); // Rightptr stores the rightmost index // of the person which // the current person cannot see int rightptr = rightindex(heights, i, n); // Maximum number of people // a person can see ans = max(ans, rightptr - leftptr - 1); } return ans; } // Driver code int main() { int N = 7; vector< int > heights{ 6, 2, 5, 4, 5, 1, 6 }; // Function call cout << max_people(heights, N) << endl; return 0; } |
Java
// JAVA code to implement the above approach import java.util.*; class GFG { // Function to find the leftmost index // of the person whose height is // greater the height of person idx. public static int leftindex( int [] heights, int idx, int n) { int h = heights[idx]; for ( int i = idx - 1 ; i >= 0 ; i--) { // If height of person i is // greater than or equal to // current person of height h // then the current person(idx) // cannot see him if (heights[i] >= h) return i; } // If a person can see all other people // who are standing on his left return - 1 ; } // Function to find the rightmost index // of the person whose height is // greater the height of person idx. public static int rightindex( int [] heights, int idx, int n) { int h = heights[idx]; for ( int i = idx + 1 ; i < n; i++) { // If height of person i is // greater than or equal to // current person of height h // then the current person(idx) // cannot see him if (heights[i] >= h) return i; } // If a person can see all other people // who are standing on his right return n; } // Function to find maximum number of people // a person can see public static int max_people( int [] heights, int n) { // Ans stores the maximum of people // a person can see int ans = 0 ; for ( int i = 0 ; i < n; i++) { // Leftptr stores the leftmost index // of the person which // the current person cannot see int leftptr = leftindex(heights, i, n); // Rightptr stores the rightmost index // of the person which // the current person cannot see int rightptr = rightindex(heights, i, n); // Maximum number of people // a person can see ans = Math.max(ans, rightptr - leftptr - 1 ); } return ans; } // Driver code public static void main(String[] args) { int N = 7 ; int [] heights = new int [] { 6 , 2 , 5 , 4 , 5 , 1 , 6 }; // Function call System.out.println(max_people(heights, N)); } } // This code is contributed by Taranpreet |
Python3
# Python code to implement the above approach # Function to find the leftmost index # of the person whose height is # greater the height of person idx. def leftindex(heights, idx, n): h = heights[idx] for i in range (idx - 1 , - 1 , - 1 ): # If height of person i is # greater than or equal to # current person of height h # then the current person(idx) # cannot see him if heights[i] > = h: return i # If a person can see all other people # who are standing on his left return - 1 # Function to find the rightmost index # of the person whose height is # greater the height of person idx. def rightindex(heights, idx, n): h = heights[idx] for i in range (idx + 1 , n): # If height of person i is # greater than or equal to # current person of height h # then the current person(idx) # cannot see him if (heights[i] > = h): return i # If a person can see all other people # who are standing on his right return n # Function to find maximum number of people # a person can see def max_people(heights, n): # Ans stores the maximum of people # a person can see ans = 0 for i in range (n): # Leftptr stores the leftmost index # of the person which # the current person cannot see leftptr = leftindex(heights, i, n) # Rightptr stores the rightmost index # of the person which # the current person cannot see rightptr = rightindex(heights, i, n) # Maximum number of people # a person can see ans = max (ans, rightptr - leftptr - 1 ) return ans # Driver code N = 7 heights = [ 6 , 2 , 5 , 4 , 5 , 1 , 6 ] # Function call print (max_people(heights, N)) # This code is contributed by rohitsingh07052. |
C#
// C# code to implement the above approach using System; class GFG { // Function to find the leftmost index // of the person whose height is // greater the height of person idx. static int leftindex( int [] heights, int idx, int n) { int h = heights[idx]; for ( int i = idx - 1; i >= 0; i--) { // If height of person i is // greater than or equal to // current person of height h // then the current person(idx) // cannot see him if (heights[i] >= h) return i; } // If a person can see all other people // who are standing on his left return -1; } // Function to find the rightmost index // of the person whose height is // greater the height of person idx. static int rightindex( int [] heights, int idx, int n) { int h = heights[idx]; for ( int i = idx + 1; i < n; i++) { // If height of person i is // greater than or equal to // current person of height h // then the current person(idx) // cannot see him if (heights[i] >= h) return i; } // If a person can see all other people // who are standing on his right return n; } // Function to find maximum number of people // a person can see static int max_people( int [] heights, int n) { // Ans stores the maximum of people // a person can see int ans = 0; for ( int i = 0; i < n; i++) { // Leftptr stores the leftmost index // of the person which // the current person cannot see int leftptr = leftindex(heights, i, n); // Rightptr stores the rightmost index // of the person which // the current person cannot see int rightptr = rightindex(heights, i, n); // Maximum number of people // a person can see ans = Math.Max(ans, rightptr - leftptr - 1); } return ans; } // Driver code public static void Main() { int N = 7; int [] heights = new int [] { 6, 2, 5, 4, 5, 1, 6 }; // Function call Console.WriteLine(max_people(heights, N)); } } // This code is contributed by Samim Hossain Mondal. |
Javascript
<script> // JavaScript code to implement the above approach // Function to find the leftmost index // of the person whose height is // greater the height of person idx. const leftindex = (heights, idx, n) => { let h = heights[idx]; for (let i = idx - 1; i >= 0; i--) { // If height of person i is // greater than or equal to // current person of height h // then the current person(idx) // cannot see him if (heights[i] >= h) return i; } // If a person can see all other people // who are standing on his left return -1; } // Function to find the rightmost index // of the person whose height is // greater the height of person idx. const rightindex = (heights, idx, n) => { let h = heights[idx]; for (let i = idx + 1; i < n; i++) { // If height of person i is // greater than or equal to // current person of height h // then the current person(idx) // cannot see him if (heights[i] >= h) return i; } // If a person can see all other people // who are standing on his right return n; } // Function to find maximum number of people // a person can see const max_people = (heights, n) => { // Ans stores the maximum of people // a person can see let ans = 0; for (let i = 0; i < n; i++) { // Leftptr stores the leftmost index // of the person which // the current person cannot see let leftptr = leftindex(heights, i, n); // Rightptr stores the rightmost index // of the person which // the current person cannot see let rightptr = rightindex(heights, i, n); // Maximum number of people // a person can see ans = Math.max(ans, rightptr - leftptr - 1); } return ans; } // Driver code let N = 7; let heights = [6, 2, 5, 4, 5, 1, 6]; // Function call document.write(max_people(heights, N)); // This code is contributed by rakeshsahni </script> |
6
Time Complexity: O(N2)
Auxiliary Space: O(N)
Efficient Approach: This problem can be solved using stacks. For every person in the row, we are trying to find the index of the next taller person on right and next taller person on the left.
- Create an array r_heights of size N to store the index of the next greater person(right).
- To find the position of the next greater person on the right:
- push the last index of the array to the stack.
- For each index ranging from N-1 to 0:
- keep popping the indices from the stack until you find an index whose height is greater than or equal to the current person’s height or until the stack is empty.
- If the stack is not empty update r_heights[i] value to match to the top of stack else r_heights[i]=N.
- Push the current index to the stack.
- Iterate from 0 to N to find the index of the next greater person on the left side for each person in the row.
- For every person in the row the number of people he can see is r_heigths[i]-l_heights[i]-1. Update the Ans as max(Ans, r_heigths[i]-l_heigths[i]-1)
Below is the implementation of above approach:
C++
// C++ code to implement the above approach #include <bits/stdc++.h> using namespace std; // Function to store the index // of next taller person on left void leftindex(vector< int > heights, vector< int >& l_heights, int n) { stack< int > st; for ( int i = 0; i < n; i++) { // While the top value of the stack // is lesser than the // current person's height while (st.empty() == false && heights[st.top()] < heights[i]) st.pop(); // If the stack is empty l_heights[i] = (st.empty() == false ) ? st.top() : (-1); st.push(i); } return ; } // Function to store the index of // next taller person on right void rightindex(vector< int >& heights, vector< int >& r_heights, int n) { // Stack to store the next // taller person on its right stack< int > st; for ( int i = n - 1; i >= 0; i--) { // If the top value of the stack // is lesser than the current height while (st.empty() == false && heights[st.top()] < heights[i]) st.pop(); // If the stack is empty r_heights[i] = (st.empty() == false ) ? st.top() : n; st.push(i); } return ; } // Function to find the maximum number // of people a person can see int max_people(vector< int > heights, int n) { // To store the answer int ans = 0; vector< int > r_heights(n), l_heights(n); leftindex(heights, l_heights, n); rightindex(heights, r_heights, n); for ( int i = 0; i < n; i++) { // Contains the leftmost index // of the person which // current person cannot see int l_index = l_heights[i]; // Contains the rightmost index // of the person which // the current person cannot see int r_index = r_heights[i]; // Calculate the maximum answer ans = max(ans, r_index - l_index - 1); } return ans; } // Driver code int main() { int N = 7; vector< int > heights{ 6, 2, 5, 4, 5, 1, 6 }; // Function call cout << max_people(heights, N) << endl; return 0; } |
Java
// Java code to implement the above approach import java.io.*; import java.util.*; class GFG { // Function to store the index // of next taller person on left public static void leftindex( int heights[], int l_heights[], int n) { Stack<Integer> st = new Stack<Integer>(); for ( int i = 0 ; i < n; i++) { // While the top value of the stack // is lesser than the // current person's height while (st.empty() == false && heights[st.peek()] < heights[i]) st.pop(); // If the stack is empty l_heights[i] = (st.empty() == false ) ? st.peek() : (- 1 ); st.push(i); } return ; } // Function to store the index of // next taller person on right public static void rightindex( int heights[], int r_heights[], int n) { // Stack to store the next // taller person on its right Stack<Integer> st = new Stack<Integer>(); for ( int i = n - 1 ; i >= 0 ; i--) { // If the top value of the stack // is lesser than the current height while (st.empty() == false && heights[st.peek()] < heights[i]) st.pop(); // If the stack is empty r_heights[i] = (st.empty() == false ) ? st.peek() : n; st.push(i); } return ; } // Function to find the maximum number // of people a person can see public static int max_people( int heights[], int n) { // To store the answer int ans = 0 ; int r_heights[] = new int [n]; int l_heights[] = new int [n]; leftindex(heights, l_heights, n); rightindex(heights, r_heights, n); for ( int i = 0 ; i < n; i++) { // Contains the leftmost index // of the person which // current person cannot see int l_index = l_heights[i]; // Contains the rightmost index // of the person which // the current person cannot see int r_index = r_heights[i]; // Calculate the maximum answer ans = Math.max(ans, r_index - l_index - 1 ); } return ans; } public static void main(String[] args) { int N = 7 ; int heights[] = { 6 , 2 , 5 , 4 , 5 , 1 , 6 }; // Function call System.out.println(max_people(heights, N)); } } // This code is contributed by Rohit Pradhan |
Python3
# Python code to implement the above approach # Function to store the index # of next taller person on left def leftindex(heights, l_heights, n): st = [] for i in range (n): # While the top value of the stack # is lesser than the # current person's height while (st ! = [] and heights[st[ - 1 ]] < heights[i]): st.pop() # If the stack is empty if st: l_heights[i] = st[ - 1 ] else : l_heights[i] = - 1 st.append(i) return l_heights # Function to store the index of # next taller person on right def rightindex(heights, r_heights, n): # Stack to store the next # taller person on its right st = [] for i in range (n - 1 , - 1 , - 1 ): # If the top value of the stack # is lesser than the current height while (st ! = [] and heights[st[ - 1 ]] < heights[i]): st.pop() # If the stack is empty if st: r_heights[i] = st[ - 1 ] else : r_heights[i] = n st.append(i) return r_heights # Function to find the maximum number # of people a person can see def max_people( heights, n): # To store the answer ans = 0 r_heights = [ 0 for i in range (n)] l_heights = [ 0 for i in range (n)] l_heights = leftindex(heights, l_heights, n) r_heights = rightindex(heights, r_heights, n) for i in range (n): # Contains the leftmost index # of the person which # current person cannot see l_index = l_heights[i] # Contains the rightmost index # of the person which # the current person cannot see r_index = r_heights[i] # Calculate the maximum answer ans = max (ans, r_index - l_index - 1 ) return ans # Driver code N = 7 heights = [ 6 , 2 , 5 , 4 , 5 , 1 , 6 ] # Function call print (max_people(heights, N)) # This code is contributed by rohitsingh07052. |
C#
// C# code to implement the above approach using System; using System.Collections; public class GFG { // Function to store the index // of next taller person on left public static void leftindex( int [] heights, int [] l_heights, int n) { Stack st = new Stack(); for ( int i = 0; i < n; i++) { // While the top value of the stack // is lesser than the // current person's height while (st.Count != 0 && heights[( int )st.Peek()] < heights[i]) st.Pop(); // If the stack is empty l_heights[i] = (st.Count != 0) ? ( int )st.Peek() : (-1); st.Push(i); } return ; } // Function to store the index of // next taller person on right public static void rightindex( int [] heights, int [] r_heights, int n) { // Stack to store the next // taller person on its right Stack st = new Stack(); for ( int i = n - 1; i >= 0; i--) { // If the top value of the stack // is lesser than the current height while (st.Count != 0 && heights[( int )st.Peek()] < heights[i]) st.Pop(); // If the stack is empty r_heights[i] = (st.Count != 0) ? ( int )st.Peek() : n; st.Push(i); } return ; } // Function to find the maximum number // of people a person can see public static int max_people( int [] heights, int n) { // To store the answer int ans = 0; int [] r_heights = new int [n]; int [] l_heights = new int [n]; leftindex(heights, l_heights, n); rightindex(heights, r_heights, n); for ( int i = 0; i < n; i++) { // Contains the leftmost index // of the person which // current person cannot see int l_index = l_heights[i]; // Contains the rightmost index // of the person which // the current person cannot see int r_index = r_heights[i]; // Calculate the maximum answer ans = Math.Max(ans, r_index - l_index - 1); } return ans; } static public void Main() { // Code int N = 7; int [] heights = { 6, 2, 5, 4, 5, 1, 6 }; // Function call Console.WriteLine(max_people(heights, N)); } } // This code is contributed by lokeshmvs21. |
Javascript
<script> // Javascript code to implement the above approach // Function to store the index // of next taller person on left function leftindex(heights, l_heights, n){ let st = [] for (let i=0;i<n;i++){ // While the top value of the stack // is lesser than the // current person's height while (st != [] && heights[st[st.length-1]] < heights[i]) st.pop() // If the stack is empty if (st.length > 0) l_heights[i] = st[st.length-1] else l_heights[i] = -1 st.push(i) } return l_heights } // Function to store the index of // next taller person on right function rightindex(heights, r_heights, n){ // Stack to store the next // taller person on its right st = [] for (let i= n-1;i>=0;i--){ // If the top value of the stack // is lesser than the current height while (st != [] && heights[st[st.length-1]] < heights[i]) st.pop() // If the stack is empty if (st.length > 0) r_heights[i] = st[st.length-1] else r_heights[i] = n st.push(i) } return r_heights } // Function to find the maximum number // of people a person can see function max_people( heights, n){ // To store the answer let ans = 0 let r_heights= new Array(n).fill(0) let l_heights= new Array(n).fill(0) l_heights = leftindex(heights, l_heights, n) r_heights = rightindex(heights, r_heights, n) for (let i=0;i<n;i++){ // Contains the leftmost index // of the person which // current person cannot see let l_index = l_heights[i] // Contains the rightmost index // of the person which // the current person cannot see let r_index = r_heights[i] // Calculate the maximum answer ans = Math.max(ans, r_index - l_index - 1) } return ans } // Driver code let N = 7 let heights = [6, 2, 5, 4, 5, 1, 6 ] // Function call document.write(max_people(heights, N)) // This code is contributed by shinjanpatra </script> |
6
Time complexity: O(N)
Auxiliary Space: O(N)
Please Login to comment...