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++ 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 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 |
# 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# 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. |
<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++ 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 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 |
# 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# 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. |
<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)