|
59 | 59 |
|
60 | 60 | <!-- 这里可写通用的实现逻辑 -->
|
61 | 61 |
|
| 62 | +**方法一:单调栈** |
| 63 | + |
| 64 | +我们观察发现,对于第 $i$ 个人来说,他能看到的人一定是按从左到右(或者从上到下)高度严格单调递增的。 |
| 65 | + |
| 66 | +因此,对于每一行,我们可以用单调栈来求出每个人能看到的人数。 |
| 67 | + |
| 68 | +具体地,我们可以倒序遍历数组,用一个从栈顶到栈底单调递增的栈 $stk$ 记录已经遍历过的人的高度。 |
| 69 | + |
| 70 | +对于第 $i$ 个人,如果栈不为空并且栈顶元素小于 $heights[i]$,累加当前第 $i$ 个人能看到的人数,然后将栈顶元素出栈,直到栈为空或者栈顶元素大于等于 $heights[i]$。如果此时栈不为空,说明栈顶元素大于等于 $heights[i]$,那么第 $i$ 个人能看到的人数还要再加 $1$。接下来,如果栈不为空并且栈顶元素等于 $heights[i]$,那么栈顶元素出栈。最后,将 $heights[i]$ 入栈,继续遍历下一个人。 |
| 71 | + |
| 72 | +这样处理过后,我们就可以得到每一行每个人能看到的人数。 |
| 73 | + |
| 74 | +同理,我们可以对每一列进行处理,得到每一列每个人能看到的人数。最后,我们将每一行和每一列的答案相加,就可以得到最终的答案。 |
| 75 | + |
| 76 | +时间复杂度 $O(m \times n)$,空间复杂度 $O(\max(m, n))$。其中 $m$ 和 $n$ 分别是数组 $heights$ 的行数和列数。 |
| 77 | + |
| 78 | +相似题目: |
| 79 | + |
| 80 | +- [1944. 队列中可以看到的人数](/solution/1900-1999/1944.Number%20of%20Visible%20People%20in%20a%20Queue/README.md) |
| 81 | + |
62 | 82 | <!-- tabs:start -->
|
63 | 83 |
|
64 | 84 | ### **Python3**
|
65 | 85 |
|
66 | 86 | <!-- 这里可写当前语言的特殊实现逻辑 -->
|
67 | 87 |
|
68 | 88 | ```python
|
| 89 | +class Solution: |
| 90 | + def seePeople(self, heights: List[List[int]]) -> List[List[int]]: |
| 91 | + def f(nums: List[int]) -> List[int]: |
| 92 | + n = len(nums) |
| 93 | + stk = [] |
| 94 | + ans = [0] * n |
| 95 | + for i in range(n - 1, -1, -1): |
| 96 | + while stk and stk[-1] < nums[i]: |
| 97 | + ans[i] += 1 |
| 98 | + stk.pop() |
| 99 | + if stk: |
| 100 | + ans[i] += 1 |
| 101 | + while stk and stk[-1] == nums[i]: |
| 102 | + stk.pop() |
| 103 | + stk.append(nums[i]) |
| 104 | + return ans |
69 | 105 |
|
| 106 | + ans = [f(row) for row in heights] |
| 107 | + m, n = len(heights), len(heights[0]) |
| 108 | + for j in range(n): |
| 109 | + add = f([heights[i][j] for i in range(m)]) |
| 110 | + for i in range(m): |
| 111 | + ans[i][j] += add[i] |
| 112 | + return ans |
70 | 113 | ```
|
71 | 114 |
|
72 | 115 | ### **Java**
|
73 | 116 |
|
74 | 117 | <!-- 这里可写当前语言的特殊实现逻辑 -->
|
75 | 118 |
|
76 | 119 | ```java
|
| 120 | +class Solution { |
| 121 | + public int[][] seePeople(int[][] heights) { |
| 122 | + int m = heights.length, n = heights[0].length; |
| 123 | + int[][] ans = new int[m][0]; |
| 124 | + for (int i = 0; i < m; ++i) { |
| 125 | + ans[i] = f(heights[i]); |
| 126 | + } |
| 127 | + for (int j = 0; j < n; ++j) { |
| 128 | + int[] nums = new int[m]; |
| 129 | + for (int i = 0; i < m; ++i) { |
| 130 | + nums[i] = heights[i][j]; |
| 131 | + } |
| 132 | + int[] add = f(nums); |
| 133 | + for (int i = 0; i < m; ++i) { |
| 134 | + ans[i][j] += add[i]; |
| 135 | + } |
| 136 | + } |
| 137 | + return ans; |
| 138 | + } |
| 139 | + |
| 140 | + private int[] f(int[] nums) { |
| 141 | + int n = nums.length; |
| 142 | + int[] ans = new int[n]; |
| 143 | + Deque<Integer> stk = new ArrayDeque<>(); |
| 144 | + for (int i = n - 1; i >= 0; --i) { |
| 145 | + while (!stk.isEmpty() && stk.peek() < nums[i]) { |
| 146 | + stk.pop(); |
| 147 | + ++ans[i]; |
| 148 | + } |
| 149 | + if (!stk.isEmpty()) { |
| 150 | + ++ans[i]; |
| 151 | + } |
| 152 | + while (!stk.isEmpty() && stk.peek() == nums[i]) { |
| 153 | + stk.pop(); |
| 154 | + } |
| 155 | + stk.push(nums[i]); |
| 156 | + } |
| 157 | + return ans; |
| 158 | + } |
| 159 | +} |
| 160 | +``` |
| 161 | + |
| 162 | +### **C++** |
77 | 163 |
|
| 164 | +```cpp |
| 165 | +class Solution { |
| 166 | +public: |
| 167 | + vector<vector<int>> seePeople(vector<vector<int>>& heights) { |
| 168 | + int m = heights.size(), n = heights[0].size(); |
| 169 | + auto f = [](vector<int>& nums) { |
| 170 | + int n = nums.size(); |
| 171 | + vector<int> ans(n); |
| 172 | + stack<int> stk; |
| 173 | + for (int i = n - 1; ~i; --i) { |
| 174 | + while (stk.size() && stk.top() < nums[i]) { |
| 175 | + ++ans[i]; |
| 176 | + stk.pop(); |
| 177 | + } |
| 178 | + if (stk.size()) { |
| 179 | + ++ans[i]; |
| 180 | + } |
| 181 | + while (stk.size() && stk.top() == nums[i]) { |
| 182 | + stk.pop(); |
| 183 | + } |
| 184 | + stk.push(nums[i]); |
| 185 | + } |
| 186 | + return ans; |
| 187 | + }; |
| 188 | + vector<vector<int>> ans; |
| 189 | + for (auto& row : heights) { |
| 190 | + ans.push_back(f(row)); |
| 191 | + } |
| 192 | + for (int j = 0; j < n; ++j) { |
| 193 | + vector<int> col; |
| 194 | + for (int i = 0; i < m; ++i) { |
| 195 | + col.push_back(heights[i][j]); |
| 196 | + } |
| 197 | + vector<int> add = f(col); |
| 198 | + for (int i = 0; i < m; ++i) { |
| 199 | + ans[i][j] += add[i]; |
| 200 | + } |
| 201 | + } |
| 202 | + return ans; |
| 203 | + } |
| 204 | +}; |
| 205 | +``` |
| 206 | +
|
| 207 | +### **Go** |
| 208 | +
|
| 209 | +```go |
| 210 | +func seePeople(heights [][]int) (ans [][]int) { |
| 211 | + f := func(nums []int) []int { |
| 212 | + n := len(nums) |
| 213 | + ans := make([]int, n) |
| 214 | + stk := []int{} |
| 215 | + for i := n - 1; i >= 0; i-- { |
| 216 | + for len(stk) > 0 && stk[len(stk)-1] < nums[i] { |
| 217 | + ans[i]++ |
| 218 | + stk = stk[:len(stk)-1] |
| 219 | + } |
| 220 | + if len(stk) > 0 { |
| 221 | + ans[i]++ |
| 222 | + } |
| 223 | + for len(stk) > 0 && stk[len(stk)-1] == nums[i] { |
| 224 | + stk = stk[:len(stk)-1] |
| 225 | + } |
| 226 | + stk = append(stk, nums[i]) |
| 227 | + } |
| 228 | + return ans |
| 229 | + } |
| 230 | + for _, row := range heights { |
| 231 | + ans = append(ans, f(row)) |
| 232 | + } |
| 233 | + n := len(heights[0]) |
| 234 | + for j := 0; j < n; j++ { |
| 235 | + col := make([]int, len(heights)) |
| 236 | + for i := range heights { |
| 237 | + col[i] = heights[i][j] |
| 238 | + } |
| 239 | + for i, v := range f(col) { |
| 240 | + ans[i][j] += v |
| 241 | + } |
| 242 | + } |
| 243 | + return |
| 244 | +} |
78 | 245 | ```
|
79 | 246 |
|
80 | 247 | ### **TypeScript**
|
81 | 248 |
|
82 | 249 | ```ts
|
83 |
| - |
| 250 | +function seePeople(heights: number[][]): number[][] { |
| 251 | + const f = (nums: number[]): number[] => { |
| 252 | + const n = nums.length; |
| 253 | + const ans: number[] = new Array(n).fill(0); |
| 254 | + const stk: number[] = []; |
| 255 | + for (let i = n - 1; ~i; --i) { |
| 256 | + while (stk.length && stk.at(-1) < nums[i]) { |
| 257 | + stk.pop(); |
| 258 | + ++ans[i]; |
| 259 | + } |
| 260 | + if (stk.length) { |
| 261 | + ++ans[i]; |
| 262 | + } |
| 263 | + while (stk.length && stk.at(-1) === nums[i]) { |
| 264 | + stk.pop(); |
| 265 | + } |
| 266 | + stk.push(nums[i]); |
| 267 | + } |
| 268 | + return ans; |
| 269 | + }; |
| 270 | + const ans: number[][] = []; |
| 271 | + for (const row of heights) { |
| 272 | + ans.push(f(row)); |
| 273 | + } |
| 274 | + const n = heights[0].length; |
| 275 | + for (let j = 0; j < n; ++j) { |
| 276 | + const col: number[] = []; |
| 277 | + for (const row of heights) { |
| 278 | + col.push(row[j]); |
| 279 | + } |
| 280 | + const add = f(col); |
| 281 | + for (let i = 0; i < ans.length; ++i) { |
| 282 | + ans[i][j] += add[i]; |
| 283 | + } |
| 284 | + } |
| 285 | + return ans; |
| 286 | +} |
84 | 287 | ```
|
85 | 288 |
|
86 | 289 | ### **...**
|
|
0 commit comments