区间合并【排序、栈】

问题

给定一组区间,合并所有有重叠的区间.

例子1:
Input: [[1,3],[2,6],[8,10],[15,18]]
Output: [[1,6],[8,10],[15,18]]
解释: 由于[1,3] 和 [2,6] 有重叠区域, 合并为 [1,6].

例子2:
Input: [[1,4],[4,5]]
Output: [[1,5]]
解释: 区间 [1,4] 和 [4,5] 可被视为重叠区间.

思路

先按左区间进行排序(右区间可以不管),然后将每一个区间和栈内的区间进行比较,如果可以合并更新栈内的区间,否则,栈内区间出栈(进入结果),并将当前区间进栈(切记!!!!)

实现

 1 import java.util.*;
 2 
 3 
 4 public class Main {
 5 
 6     public static class Block {
 7         int left;
 8         int right;
 9 
10         public Block(int left, int right) {
11             this.left = left;
12             this.right = right;
13         }
14     }
15 
16     public static void main(String[] args) {
17         Scanner scan = new Scanner(System.in);
18 
19         while (scan.hasNext()) {
20             int n = scan.nextInt();
21             Block[] arr = new Block[n];
22             for (int i = 0; i < n; ++i) {
23                 int left = scan.nextInt();
24                 int right = scan.nextInt();
25                 arr[i] = new Block(left, right);
26             }
27             Arrays.sort(arr, new Comparator<Block>() {
28                 @Override
29                 public int compare(Block o1, Block o2) {
30                     int p = o1.left - o2.left;
31                     if (p != 0) {
32                         return p;
33                     }
34 
35                     return o1.right - o2.right;
36                 }
37             });
38             int rl = 0, rr = 0;
39             boolean empty = true;//指示栈是否为空
40             List<Block> res = new LinkedList<Block>();
41 
42             for (int i = 0; i < n; ++i) {
43                 if (empty) {
44                     rl = arr[i].left;
45                     rr = arr[i].right;
46                     empty = false;
47                     continue;
48                 }
49 
50                 if (arr[i].left <= rr) {
51                     rr = Math.max(rr, arr[i].right);
52                 } else {
53                     res.add(new Block(rl, rr));
54                     --i;//--i的目的是将当前区间入栈,因为empty为空了,当前区间可以直接进栈
55                     empty = true;
56                 }
57             }
58 
59             if (!empty) {
60                 res.add(new Block(rl, rr));
61             }
62 
63             for (Block b : res) {
64                 System.out.println(b.left + "->" + b.right);
65             }
66 
67         }
68 
69     }
70 }
原文地址:https://www.cnblogs.com/oldBook/p/13557839.html