代码改变世界

[LeetCode] 2282. Number of People That Can Be Seen in a Grid_Medium tag: stack.

2023-10-11 05:59  Johnson_强生仔仔  阅读(4)  评论(0编辑  收藏  举报

You are given an m x n 0-indexed 2D array of positive integers heights where heights[i][j] is the height of the person standing at position (i, j).

A person standing at position (row1, col1) can see a person standing at position (row2, col2) if:

  • The person at (row2, col2) is to the right or below the person at (row1, col1). More formally, this means that either row1 == row2 and col1 < col2 or row1 < row2 and col1 == col2.
  • Everyone in between them is shorter than both of them.

Return an m x n 2D array of integers answer where answer[i][j] is the number of people that the person at position (i, j) can see.

 

Example 1:

Input: heights = [[3,1,4,2,5]]
Output: [[2,1,2,1,0]]
Explanation:
- The person at (0, 0) can see the people at (0, 1) and (0, 2).
  Note that he cannot see the person at (0, 4) because the person at (0, 2) is taller than him.
- The person at (0, 1) can see the person at (0, 2).
- The person at (0, 2) can see the people at (0, 3) and (0, 4).
- The person at (0, 3) can see the person at (0, 4).
- The person at (0, 4) cannot see anybody.

Example 2:

Input: heights = [[5,1],[3,1],[4,1]]
Output: [[3,1],[2,1],[1,0]]
Explanation:
- The person at (0, 0) can see the people at (0, 1), (1, 0) and (2, 0).
- The person at (0, 1) can see the person at (1, 1).
- The person at (1, 0) can see the people at (1, 1) and (2, 0).
- The person at (1, 1) can see the person at (2, 1).
- The person at (2, 0) can see the person at (2, 1).
- The person at (2, 1) cannot see anybody.

 

Constraints:

  • 1 <= heights.length <= 400
  • 1 <= heights[i].length <= 400
  • 1 <= heights[i][j] <= 105

 

这个题目实际上就是[LeetCode] 1944. Number of Visible People in a Queue_Hard tag: stack的follow up, 但是有点不一样的是这个题目允许有duplicates.

1. if input is [[4,2,1,1,3]], output 为[[ 2, 2, 1, 1, 0]]

    如果只用1944的code, 那么output为[[ 2, 2, 2, 1, 0]], 所以需要用一个额外的variable equal,来判断如果有equal那么看不到下一个大点的,将if stack 变成 if stack and not equal.

2. 将每一行作为一个stack来走一遍

3. 用同样的方式将每一列作为一个stack来走一遍

T: O(m * n).  S: O(m * n)

class Solution:
    def seePeople(self, heights: List[List[int]]) -> List[List[int]]:
        m, n = len(heights), len(heights[0])
        ans = [[0] * n for _ in range(m)]
        for i in range(m):
            stack = [] # strict decrease stack
            for j in range(n - 1, -1, -1):
                equal = False
                while stack and stack[-1] <= heights[i][j]:
                    h_pop = stack.pop()
                    if h_pop == heights[i][j]:
                        equal = True
                    ans[i][j] += 1
                if stack and not equal:
                    ans[i][j] += 1
                stack.append(heights[i][j])
        
        for j in range(n):
            stack = []
            for i in range(m - 1, -1, -1):
                equal = False
                while stack and stack[-1] <= heights[i][j]:
                    h_pop = stack.pop()
                    if h_pop == heights[i][j]:
                        equal = True
                    ans[i][j] += 1
                if stack and not equal:
                    ans[i][j] += 1
                stack.append(heights[i][j])
        return ans