1762. Buildings With an Ocean View - Explanation

Problem Link

Description

You are given an array of integers heights of size n representing a row of buildings, where heights[i] is the height of the ith building.

There is an ocean located to the far right of the buildings. A building has an ocean view if every building to its right is strictly shorter than it.

Return a list of indices (0-indexed) of the buildings that have an ocean view, sorted in increasing order.

Example 1:

Input: heights = [4,2,3,2,1]

Output: [0,2,3,4]

Example 2:

Input: heights = [1,3,2,4,2,5,1]

Output: [5,6]

Example 3:

Input: heights = [9,8,7,7,6,5,4,3]

Output: [0,1,3,4,5,6,7]

Constraints:

  • 1 <= heights.length <= 100,000.
  • 1 <= heights[i] <= 1,000,000,000


Topics

Company Tags

Please upgrade to NeetCode Pro to view company tags.



Prerequisites

Before attempting this problem, you should be comfortable with:

  • Arrays - Traversing and comparing elements in an array
  • Monotonic Stack - Understanding how to maintain a stack with elements in decreasing/increasing order
  • Reverse Iteration - Processing arrays from right to left for optimization

1. Brute Force

Intuition

A building has an ocean view if no building to its right is taller or equal in height. The ocean is to the right of all buildings. The simplest approach is to check each building individually: for every building, scan all buildings to its right and see if any of them block the view.

Algorithm

  1. Iterate through each building from left to right.
  2. For each building at index i, check all buildings from index i+1 to the end.
  3. If any building to the right has height greater than or equal to the current building, mark this building as having no ocean view.
  4. If no taller or equal building is found to the right, add this index to the result.
  5. Return all indices of buildings with ocean views.
class Solution:
    def findBuildings(self, heights: List[int]) -> List[int]:
        n = len(heights)
        res = []

        for i in range(n):
            flag = True
            for j in range(i + 1, n):
                if heights[i] <= heights[j]:
                    flag = False
                    break
            if flag:
                res.append(i)

        return res

Time & Space Complexity

  • Time complexity: O(n2)O(n ^ 2)
  • Space complexity: O(n)O(n) for the output array.

2. Monotonic Stack

Intuition

We can use a monotonic decreasing stack to efficiently track buildings with ocean views. As we scan from left to right, whenever we encounter a building that is taller than or equal to the building at the top of the stack, the stack building loses its ocean view (because this new building blocks it). We pop such buildings and push the current one. The remaining buildings in the stack at the end all have ocean views.

Algorithm

  1. Initialize an empty stack to store building indices.
  2. Iterate through buildings from left to right.
  3. While the stack is not empty and the current building's height is greater than or equal to the height of the building at the stack top:
    • Pop from the stack (that building no longer has an ocean view).
  4. Push the current building index onto the stack.
  5. Return the stack contents as the result (indices are already in increasing order).
class Solution:
    def findBuildings(self, heights: List[int]) -> List[int]:
        stack = []

        for i, h in enumerate(heights):
            while stack and heights[stack[-1]] <= h:
                stack.pop()
            stack.append(i)

        return stack

Time & Space Complexity

  • Time complexity: O(n)O(n)
  • Space complexity: O(n)O(n)

3. Greedy

Intuition

The most elegant approach is to scan from right to left. A building has an ocean view if it is strictly taller than every building to its right. We only need to track the maximum height seen so far as we traverse from the rightmost building toward the left.

Algorithm

  1. Start from the rightmost building (it always has an ocean view) and add it to the result.
  2. Move leftward through the buildings.
  3. For each building, if its height is greater than the height of the last building added to our result (which represents the tallest building seen so far), add this building to the result.
  4. Reverse the result since we collected indices from right to left but need them in increasing order.
  5. Return the result.
class Solution:
    def findBuildings(self, heights: List[int]) -> List[int]:
        res = [len(heights) - 1]
        for i in range(len(heights) - 2, -1, -1):
            if heights[i] > heights[res[-1]]:
                res.append(i)
        res.reverse()
        return res

Time & Space Complexity

  • Time complexity: O(n)O(n)
  • Space complexity:
    • O(1)O(1) extra space.
    • O(n)O(n) for the output array.

Common Pitfalls

Using Wrong Comparison Operator

A building loses its ocean view if any building to its right is taller OR EQUAL in height. Using strictly greater than (>) instead of greater than or equal (>=) incorrectly keeps buildings that are blocked by same-height buildings.

# Wrong: same height doesn't block
if heights[i] > heights[j]:  # Misses equal heights

# Correct: equal or greater blocks the view
if heights[i] <= heights[j]:
    has_view = False

Forgetting to Reverse the Result

When iterating from right to left (the optimal approach), indices are collected in reverse order. Forgetting to reverse the final result returns indices in descending order instead of the required ascending order.

Not Handling Single Building Case

An array with one building should return [0] since the only building always has an ocean view. Edge case handling ensures the rightmost building is always included in the initial result.