Skip to main content

LeetCode 0218

Hung NguyenJune 28, 2024About 3 mindsaleetcodedsaleetcode

0218. The Skyline Problem

Tóm tắt bài toán

Mô tả: Đường chân trời của một thành phố được tạo thành từ việc quan sát các tòa nhà trong thành phố từ một khoảng cách xa.

Cho một mảng buildings gồm các tọa độ và chiều cao của các tòa nhà. Mỗi phần tử buildings[i] = [left_i, right_i, height_i] đại diện cho tọa độ x bên trái của tòa nhà thứ i, tọa độ x bên phải của tòa nhà thứ i và chiều cao của tòa nhà thứ i.

Yêu cầu: Trả về đường chân trời được tạo thành từ các tòa nhà này.

Lưu ý: Đường chân trời không được chứa các đoạn ngang có cùng chiều cao liên tiếp.

Ví dụ:

Ý tưởng giải quyết

Có thể thấy rằng: Tọa độ x của các điểm quyết định nằm trên biên trái và biên phải của các tòa nhà.

Chúng ta có thể lưu trữ tọa độ cao nhất của biên trái và biên phải vào mảng points, sau đó sắp xếp theo tọa độ x và chiều cao.

Sau đó, chúng ta sử dụng một "cột quét" song song với trục y, quét từ trái sang phải qua tất cả các tọa độ. Điều này sẽ chia các tòa nhà thành các hình chữ nhật đều nhau.

Dễ thấy: Hai tọa độ liền kề x và chiều cao tạo thành một hình chữ nhật. Tọa độ x của hai tọa độ liền kề có thể lấy từ mảng đã được sắp xếp points và chiều cao của hình chữ nhật có thể được duy trì bằng một hàng đợi ưu tiên (heap) max_heap. Sử dụng mảng ans để lưu trữ kết quả.

Khi quét từ trái sang phải:

Vì ba cạnh có cùng chiều cao nên chúng ta sử dụng biến prev để lưu trữ chiều cao trước đó.

Cuối cùng, trả về kết quả ans.

Code

from sortedcontainers import SortedList

class Solution:
    def getSkyline(self, buildings: List[List[int]]) -> List[List[int]]:
        ans = []
        points = []
        for building in buildings:
            left, right, hight = building[0], building[1], building[2]
            points.append([left, -hight])
            points.append([right, hight])
        points.sort(key=lambda x:(x[0], x[1]))

        prev = 0
        max_heap = SortedList([prev])

        for point in points:
            x, height = point[0], point[1]
            if height < 0:
                max_heap.add(-height)
            else:
                max_heap.remove(height)

            curr = max_heap[-1]
            if curr != prev:
                ans.append([x, curr])
                prev = curr
        return ans