LeeCode (Heap) 218_ Skyline Issue

LeeCode (Heap) 218_ Skyline Issue

Topic:
The skyline of a city is the outer contour of the outline formed by all the buildings in the city viewed from a distance. Give you the location and height of all the buildings, please return to the skyline formed by these buildings.

The geometric information of each building is represented by the array buildings, where the triplet buildings[i] = [lefti, righti, heighti] represents:

lefti is the x coordinate of the left edge of the i-th building.
righti is the x coordinate of the right edge of the i-th building.
heighti is the height of the i-th building.
The skyline should be expressed as a list of "key points" in the format [[x1,y1],[x2,y2],...] and sorted by x coordinate. The key point is the left end of the horizontal line segment. The last point in the list is the end point of the rightmost building. The y coordinate is always 0 and is only used to mark the end point of the skyline. In addition, the ground between any two adjacent buildings should be considered part of the skyline outline.

Note: There must be no continuous horizontal lines of the same height in the output skyline. For example, […[2 3], [4 5], [7 5], [11 5], [12 7]…] are incorrect answers; three lines with a height of 5 should be merged into one in the final output: […[2 3], [4 5], [12 7], …]

Example 1:
Insert picture description here

Input: buildings = [[2,9,10],[3,7,15],[5,12,12],[15,20,10],[19,24,8]]
Output: [[2 ,10],[3,15],[7,12],[12,0],[15,10],[20,8],[24,0]]
Explanation:
Figure A shows all the buildings entered the position and height,
panel B shows skyline formed from these structures. The red dots in Figure B indicate the key points in the output list.
Example 2:

Input: buildings = [[0,2,3],[2,5,3]]
Output: [[0,3],[5,0]]

Source: LeetCode
Link: https://leetcode-cn.com/problems/the-skyline-problem
Copyright is owned by LeetCode . For commercial reprints, please contact the official authorization. For non-commercial reprints, please indicate the source.

Problem-solving ideas:

  1. First abstract all the buildings into two points (one upper left corner, one upper right corner) and put them into the points linked list, and arrange them in ascending order of the value of x.
    There are three cases when x is the same:

① When the abbreviations of point1 and point2 (p1, p2) are both upper left corner points, y1>y2, then the higher height p1 is placed in front of p2.
②When p1 and p2 are both upper left corner points, y1<y2, then p1 with the smaller height is placed in front of p2.
③When p1 is the upper left corner point and p2 is the upper right corner point, the upper left corner point p1 is placed in front.

  1. Create a priority queue to store the height of all buildings that have not encountered the upper right corner point. When the upper right corner point is encountered, the height of the point is deleted from the queue, and the current highest height is updated to determine whether there is a change. This point is added to the result set res.

Java code:

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.PriorityQueue;
import java.util.Queue;

public class 天际线 {
    
    
	public List<List<Integer>> getSkyline(int[][] buildings) {
    
    
		List<List<Integer>> points = new ArrayList<>();
		List<List<Integer>> res = new ArrayList<>();
		int n = buildings.length;
		
		for(int b[] : buildings){
    
    
			List<Integer> p1 = new ArrayList<>();
			p1.add(b[0]);
			p1.add(-b[2]);
			points.add(p1);
			
			List<Integer> p2 = new ArrayList<>();
			p2.add(b[1]);
			p2.add(b[2]);
			points.add(p2);
		}
		
		Collections.sort(points,new Comparator<List<Integer>>() {
    
    
			@Override
			public int compare(List<Integer> p1, List<Integer> p2) {
    
    
				int x1 = p1.get(0);
				int x2 = p2.get(0);
				int y1 = p1.get(1);
				int y2 = p2.get(1);
				if(x1 != x2){
    
    
					return x1 - x2;
				}else{
    
    
					return y1 - y2;
				}
			}
		});
		
		
		Queue<Integer> queue = new PriorityQueue<>(new Comparator<Integer>() {
    
    
		@Override
		public int compare(Integer o1, Integer o2) {
    
    
			// TODO Auto-generated method stub
			return o2 - o1;
		}
		});
		
		//放入起始高度
		queue.offer(0);
		
		int preMax = 0;
		
		for(List<Integer> p : points){
    
    
			int x = p.get(0);
			int y = p.get(1);
			
			//左上角
			if(y<0){
    
    
				queue.offer(-y);
			}else{
    
    
			//右上角
				queue.remove(y);
			}
			
			//获取栈头元素,(因queue采用了降序排列,所以栈头元素为最大值)
			int curMax = queue.peek();
			
			//当前最大值出现变化
			if(curMax != preMax){
    
    
				List<Integer> temp = new ArrayList<>();
	            temp.add(x);
	            temp.add(curMax);
	            res.add(temp);
	            preMax = curMax;
			}
			
		}
		return res;
	}
}

Guess you like

Origin blog.csdn.net/u013456390/article/details/112213183