一、區間相關問題:選擇不相交的區間java
數軸上有n個開區間(begin,end),儘可能選擇數量最多的區間,使得這些區間兩兩沒有交集。【某國王打算讓將軍們去守衛長城(可當作一條線段),每一個人選擇一個本身喜歡的區間段,爲了讓最多的將軍能守衛本身想守衛的地方,怎麼安排是最合理的呢?例如:長城的區間段是[1,1000],每一個將軍選擇的區間段都在這個範圍內,任意兩個將軍守衛的地方不能有重合的地方,不然會出現爭執,兩個點的交集不算交集】算法
好比輸入:ide
1 2 324 2 320 424 3 259 342 4 371 888 5 264 634 6 909 982 7 117 653 8 677 929 9 656 707 10 297 915 11 904 943 12 309 564 13 564 601 14 675 876 15 33 89 16 363 912 17 226 952 18 86 129 19 216 339 20 258 857
則對應輸出this
第1個區間段爲[33,89] 第2個區間段爲[216,339] 第3個區間段爲[564,601] 第4個區間段爲[656,707] 第5個區間段爲[904,943] 最多有5個區間段
解題思路:使用貪心算法,貪心策略爲按照end從小到大的順序將全部區間進行排序,每次取與以前的區間不相交的第一個區間spa
public class Changcheng implements Comparable<Changcheng>{ private int begin; private int end; public Changcheng(int begin, int end) { this.begin = begin; this.end = end; } public int getBegin() { return begin; } public void setBegin(int begin) { this.begin = begin; } public int getEnd() { return end; } public void setEnd(int end) { this.end = end; } @Override public int compareTo(Changcheng o) { if(this.getEnd() > o.getEnd()) { return 1; }else if(this.getEnd() < o.getEnd()) { return -1; } return 0; } }
import java.util.Arrays; public class Solution { public static void main(String[] args) { Changcheng[] changcheng = new Changcheng[20]; changcheng[0] = new Changcheng(2, 324); changcheng[1] = new Changcheng(320, 424); changcheng[2] = new Changcheng(259, 342); changcheng[3] = new Changcheng(371, 888); changcheng[4] = new Changcheng(264, 634); changcheng[5] = new Changcheng(909, 982); changcheng[6] = new Changcheng(117, 653); changcheng[7] = new Changcheng(677, 929); changcheng[8] = new Changcheng(656, 707); changcheng[9] = new Changcheng(297, 915); changcheng[10] = new Changcheng(904, 943); changcheng[11] = new Changcheng(309, 564); changcheng[12] = new Changcheng(564, 601); changcheng[13] = new Changcheng(675, 876); changcheng[14] = new Changcheng(33, 89); changcheng[15] = new Changcheng(363, 912); changcheng[16] = new Changcheng(226, 952); changcheng[17] = new Changcheng(86, 129); changcheng[18] = new Changcheng(216, 339); changcheng[19] = new Changcheng(258, 857); process(changcheng); } private static void process(Changcheng[] changcheng) { //按照end從小到大的順序將全部區間進行排序 Arrays.sort(changcheng); int end = changcheng[0].getEnd(); int count = 1; System.out.println("第" + count + "個區間段爲[" + changcheng[0].getBegin() + "," + end + "]"); for(int i=1; i<changcheng.length; i++) { //尋找不相交的區間 if(changcheng[i].getBegin() >= end) { count++; end = changcheng[i].getEnd(); System.out.println("第" + count + "個區間段爲[" + changcheng[i].getBegin() + "," + end + "]"); } } System.out.println("最多有" + count + "個不重複的區間段"); } }
二、區間相關問題:區間選點問題code
數軸上有n個閉區間[begin,end],取儘可能少的點,使得每一個區間內都至少有一個點(不一樣區間內含的點能夠是同一個)blog
例如輸入:排序
[0, 3] [16, 20] [2, 8] [8, 21] [15, 17] [10, 12] [19, 21]
輸出get
第1個點爲:3 第2個點爲:12 第3個點爲:17 第4個點爲:21 最少須要選擇4個點
解題思路:使用貪心算法,貪心策略爲按照end從小到大的順序將區間排序(end相同時,begin從大到小排序),則若是出現區間包含的狀況,小區間必定排在前面,每一個區間取最後一個點。io
public class Changcheng implements Comparable<Changcheng>{ private int begin; private int end; public Changcheng(int begin, int end) { this.begin = begin; this.end = end; } public int getBegin() { return begin; } public void setBegin(int begin) { this.begin = begin; } public int getEnd() { return end; } public void setEnd(int end) { this.end = end; } //按照end從小到大的順序將區間排序(end相同時,begin從大到小排序) @Override public int compareTo(Changcheng o) { if(this.getEnd() > o.getEnd()) { return 1; }else if(this.getEnd() < o.getEnd()) { return -1; }else { if(this.getBegin() > o.getBegin()) { return -1; }else if(this.getBegin() < o.getBegin()) { return 1; } return 0; } } //判斷當前區間是否包含指定點 public boolean contains(int point) { if(point >= this.getBegin() && point <= this.getEnd()) { return true; } return false; } }
import java.util.Arrays; public class Solution { public static void main(String[] args) { Changcheng[] changcheng = new Changcheng[7]; changcheng[0] = new Changcheng(0, 3); changcheng[1] = new Changcheng(16, 20); changcheng[2] = new Changcheng(2, 8); changcheng[3] = new Changcheng(8, 21); changcheng[4] = new Changcheng(15, 17); changcheng[5] = new Changcheng(10, 12); changcheng[6] = new Changcheng(19, 21); process(changcheng); } //區間選點問題 private static void process(Changcheng[] changcheng) { Arrays.sort(changcheng); int count = 1; int point = changcheng[0].getEnd(); System.out.println("第" + count + "個點爲:" + point); for(int i=1; i<changcheng.length; i++) { if(!changcheng[i].contains(point)) { point = changcheng[i].getEnd(); count++; System.out.println("第" + count + "個點爲:" + point); } } System.out.println("最少須要選擇" + count + "個點"); } }