Given an array arr[], where arr[i] represents the height of the i-th person standing in a line, a person i can see another person j if arr[j] is smaller than arr[i] and there is no person k standing between them such that arr[k] is greater than or equal to arr[i].
Each person can see in both directions (front and back). Find the maximum number of people that any person can see, including themselves.
Examples:
Input: arr[] = [6, 2, 5, 4, 5, 1, 6]
Output: 6
Explanation:
Person at index 0 (height = 6) can see everyone from index 1 to 5, plus self. Total = 6.
Person at index 1 (height = 2) is blocked on both sides and can see only self. Total = 1.
Person at index 2 (height = 5) can see index 1 on the left, index 3 on the right, and self. Total = 3.
Person at index 3 (height = 4) is blocked on both sides and can see only self. Total = 1.
Person at index 4 (height = 5) can see index 3 on the left, index 5 on the right, and self. Total = 3.
Person at index 5 (height = 1) is the shortest and can see only self. Total = 1.
Person at index 6 (height = 6) can see everyone from index 1 to 5, plus self. Total = 6.The maximum count is 6, achieved by the persons at index 0 and index 6.
Input: arr[] = [1, 3, 6, 4]
Output: 4
Explanation: Person with height 6 can see persons with heights 1, 3 on the left and 4 on the right, along with himself, giving a total of 4.
Table of Content
[Naive Approach] Using Nested Loops - O(n2) Time and O(1) Space
The idea is to iterate over each person and count how many people they can see in both directions. For each person, scan left and right until you encounter someone taller or equal in height, counting all shorter people along the way. Keep track of the maximum count across all people.
#include <iostream>
#include <vector>
using namespace std;
int maxPeople(vector<int> &arr) {
int n = arr.size();
int maxCount = 0;
for (int i = 0; i < n; i++) {
int count = 1;
// Check left side
for (int j = i - 1; j >= 0; j--) {
if (arr[j] < arr[i])
count++;
if (arr[j] >= arr[i])
break;
}
// Check right side
for (int j = i + 1; j < n; j++) {
if (arr[j] < arr[i])
count++;
if (arr[j] >= arr[i])
break;
}
if (count > maxCount)
maxCount = count;
}
return maxCount;
}
int main() {
vector<int> arr = {6, 2, 5, 4, 5, 1, 6};
cout << maxPeople(arr) << endl;
return 0;
}
public class GfG{
static int maxPeople(int[] arr) {
int n = arr.length;
int maxCount = 0;
for (int i = 0; i < n; i++) {
int count = 1;
// Check left side
for (int j = i - 1; j >= 0; j--) {
if (arr[j] < arr[i])
count++;
if (arr[j] >= arr[i])
break;
}
// Check right side
for (int j = i + 1; j < n; j++) {
if (arr[j] < arr[i])
count++;
if (arr[j] >= arr[i])
break;
}
if (count > maxCount)
maxCount = count;
}
return maxCount;
}
public static void main(String[] args) {
int[] arr = {6, 2, 5, 4, 5, 1, 6};
System.out.println(maxPeople(arr));
}
}
def maxPeople(arr):
n = len(arr)
maxCount = 0
for i in range(n):
count = 1
# Check left side
for j in range(i - 1, -1, -1):
if arr[j] < arr[i]:
count += 1
if arr[j] >= arr[i]:
break
# Check right side
for j in range(i + 1, n):
if arr[j] < arr[i]:
count += 1
if arr[j] >= arr[i]:
break
maxCount = max(maxCount, count)
return maxCount
if __name__=="__main__":
arr = [6, 2, 5, 4, 5, 1, 6]
print(maxPeople(arr))
using System;
class GfG {
static int maxPeople(int[] arr) {
int n = arr.Length;
int maxCount = 0;
for (int i = 0; i < n; i++)
{
int count = 1;
// Check left side
for (int j = i - 1; j >= 0; j--)
{
if (arr[j] < arr[i])
count++;
if (arr[j] >= arr[i])
break;
}
// Check right side
for (int j = i + 1; j < n; j++)
{
if (arr[j] < arr[i])
count++;
if (arr[j] >= arr[i])
break;
}
if (count > maxCount)
maxCount = count;
}
return maxCount;
}
static void Main()
{
int[] arr = { 6, 2, 5, 4, 5, 1, 6 };
Console.WriteLine(maxPeople(arr));
}
}
function maxPeople(arr) {
const n = arr.length;
let maxCount = 0;
for (let i = 0; i < n; i++) {
let count = 1;
// Check left side
for (let j = i - 1; j >= 0; j--) {
if (arr[j] < arr[i])
count++;
if (arr[j] >= arr[i])
break;
}
// Check right side
for (let j = i + 1; j < n; j++) {
if (arr[j] < arr[i])
count++;
if (arr[j] >= arr[i])
break;
}
if (count > maxCount)
maxCount = count;
}
return maxCount;
}
// Driver Code
let arr = [6, 2, 5, 4, 5, 1, 6];
console.log(maxPeople(arr));
Output
6
[Expected Approach] Using Monotonic Stack - O(n) Time and O(n) Space
The idea is to use the concepts of Previous Greater Element and Next Greater Element. For each person at index i, the Previous Greater Element gives the nearest taller or equal person on the left, while the Next Greater Element gives the nearest taller or equal person on the right.
These two boundaries define the visible range for person i. Using stacks, both values can be computed efficiently. Finally, we count how many people each person can see and maintain the maximum across all indices.
#include <iostream>
#include <vector>
#include <stack>
using namespace std;
// Function to compute Previous Greater Element for each index
vector<int> previousGreater(vector<int>& arr) {
int n = arr.size();
vector<int> prev(n, -1);
stack<int> st;
for (int i = 0; i < n; i++) {
while (!st.empty() && arr[st.top()] < arr[i]) {
st.pop();
}
if (!st.empty()) prev[i] = st.top();
st.push(i);
}
return prev;
}
// Function to compute Next Greater Element for each index
vector<int> nextGreater(vector<int>& arr) {
int n = arr.size();
vector<int> next(n, n);
stack<int> st;
for (int i = n - 1; i >= 0; i--) {
while (!st.empty() && arr[st.top()] < arr[i]) {
st.pop();
}
if (!st.empty()) next[i] = st.top();
st.push(i);
}
return next;
}
int maxPeople(vector<int>& arr) {
int n = arr.size();
// Compute Previous Greater and Next Greater
vector<int> prev = previousGreater(arr);
vector<int> next = nextGreater(arr);
int maxCount = 0;
for (int i = 0; i < n; i++) {
int leftBound = (prev[i] == -1 ? 0 : prev[i] + 1);
int rightBound = (next[i] == n ? n - 1 : next[i] - 1);
// Range size gives how many people visible including self
int count = rightBound - leftBound + 1;
maxCount = max(maxCount, count);
}
return maxCount;
}
int main() {
vector<int> arr = {6, 2, 5, 4, 5, 1, 6};
cout << maxPeople(arr) << endl;
return 0;
}
import java.util.Arrays;
import java.util.Stack;
public class GfG {
// Function to compute Previous Greater Element for each index
static int[] previousGreater(int[] arr) {
int n = arr.length;
int[] prev = new int[n];
Arrays.fill(prev, -1);
Stack<Integer> st = new Stack<>();
for (int i = 0; i < n; i++) {
while (!st.isEmpty() && arr[st.peek()] < arr[i]) {
st.pop();
}
if (!st.isEmpty()) prev[i] = st.peek();
st.push(i);
}
return prev;
}
// Function to compute Next Greater Element for each index
static int[] nextGreater(int[] arr) {
int n = arr.length;
int[] next = new int[n];
Arrays.fill(next, n);
Stack<Integer> st = new Stack<>();
for (int i = n - 1; i >= 0; i--) {
while (!st.isEmpty() && arr[st.peek()] < arr[i]) {
st.pop();
}
if (!st.isEmpty()) next[i] = st.peek();
st.push(i);
}
return next;
}
static int maxPeople(int[] arr) {
int n = arr.length;
// Compute Previous Greater and Next Greater
int[] prev = previousGreater(arr);
int[] next = nextGreater(arr);
int maxCount = 0;
for (int i = 0; i < n; i++) {
int leftBound = (prev[i] == -1 ? 0 : prev[i] + 1);
int rightBound = (next[i] == n ? n - 1 : next[i] - 1);
// Range size gives how many people visible including self
int count = rightBound - leftBound + 1;
maxCount = Math.max(maxCount, count);
}
return maxCount;
}
public static void main(String[] args) {
int[] arr = {6, 2, 5, 4, 5, 1, 6};
System.out.println(maxPeople(arr));
}
}
def previousGreater(arr):
n = len(arr)
prev = [-1] * n
st = []
for i in range(n):
while st and arr[st[-1]] < arr[i]:
st.pop()
if st:
prev[i] = st[-1]
st.append(i)
return prev
def nextGreater(arr):
n = len(arr)
next_ = [n] * n
st = []
for i in range(n - 1, -1, -1):
while st and arr[st[-1]] < arr[i]:
st.pop()
if st:
next_[i] = st[-1]
st.append(i)
return next_
def maxPeople(arr):
n = len(arr)
# Compute Previous Greater and Next Greater
prev = previousGreater(arr)
next_ = nextGreater(arr)
maxCount = 0
for i in range(n):
leftBound = 0 if prev[i] == -1 else prev[i] + 1
rightBound = n - 1 if next_[i] == n else next_[i] - 1
# Range size gives how many people visible including self
count = rightBound - leftBound + 1
maxCount = max(maxCount, count)
return maxCount
if __name__ == "__main__":
arr = [6, 2, 5, 4, 5, 1, 6]
print(maxPeople(arr))
using System;
using System.Collections.Generic;
class GFG {
// Function to compute Previous Greater Element for each index
static int[] previousGreater(int[] arr) {
int n = arr.Length;
int[] prev = new int[n];
Array.Fill(prev, -1);
Stack<int> st = new Stack<int>();
for (int i = 0; i < n; i++) {
while (st.Count > 0 && arr[st.Peek()] < arr[i]) {
st.Pop();
}
if (st.Count > 0) prev[i] = st.Peek();
st.Push(i);
}
return prev;
}
// Function to compute Next Greater Element for each index
static int[] nextGreater(int[] arr) {
int n = arr.Length;
int[] next = new int[n];
Array.Fill(next, n);
Stack<int> st = new Stack<int>();
for (int i = n - 1; i >= 0; i--) {
while (st.Count > 0 && arr[st.Peek()] < arr[i]) {
st.Pop();
}
if (st.Count > 0) next[i] = st.Peek();
st.Push(i);
}
return next;
}
static int maxPeople(int[] arr) {
int n = arr.Length;
// Compute Previous Greater and Next Greater
int[] prev = previousGreater(arr);
int[] next = nextGreater(arr);
int maxCount = 0;
for (int i = 0; i < n; i++) {
int leftBound = (prev[i] == -1 ? 0 : prev[i] + 1);
int rightBound = (next[i] == n ? n - 1 : next[i] - 1);
// Range size gives how many people visible including self
int count = rightBound - leftBound + 1;
maxCount = Math.Max(maxCount, count);
}
return maxCount;
}
static void Main() {
int[] arr = {6, 2, 5, 4, 5, 1, 6};
Console.WriteLine(maxPeople(arr));
}
}
// Function to compute Previous Greater Element for each index
function previousGreater(arr) {
let n = arr.length;
let prev = new Array(n).fill(-1);
let st = [];
for (let i = 0; i < n; i++) {
while (st.length > 0 && arr[st[st.length - 1]] < arr[i]) {
st.pop();
}
if (st.length > 0) prev[i] = st[st.length - 1];
st.push(i);
}
return prev;
}
// Function to compute Next Greater Element for each index
function nextGreater(arr) {
let n = arr.length;
let next = new Array(n).fill(n);
let st = [];
for (let i = n - 1; i >= 0; i--) {
while (st.length > 0 && arr[st[st.length - 1]] < arr[i]) {
st.pop();
}
if (st.length > 0) next[i] = st[st.length - 1];
st.push(i);
}
return next;
}
function maxPeople(arr) {
let n = arr.length;
// Compute Previous Greater and Next Greater
let prev = previousGreater(arr);
let next = nextGreater(arr);
let maxCount = 0;
for (let i = 0; i < n; i++) {
let leftBound = (prev[i] === -1 ? 0 : prev[i] + 1);
let rightBound = (next[i] === n ? n - 1 : next[i] - 1);
// Range size gives how many people visible including self
let count = rightBound - leftBound + 1;
maxCount = Math.max(maxCount, count);
}
return maxCount;
}
// Driver Code
let arr = [6, 2, 5, 4, 5, 1, 6];
console.log(maxPeople(arr));
Output
6