贪心算法
求活动最大数
有若干个活动,每个活动有开始时间和结束时间,只有一个教室,活动之间不能交叠,求最多安排多少个活动?
public static class Activity {
int start;//活动开始时间
int end;//活动结束时间
}
//贪心算法,每次取可相容的活动中结束时间最早的那个,为剩下的活动留下更多的可选时间。
private static int greedy(Activity[] a) {
int res = 0;//活动集合中最大可相容数
Arrays.sort(a, Comparator.comparingInt(o -> o.end));//按结束时间从小到大排
int lastEnd = Integer.MIN_VALUE;
for (int i = 0; i <a.length ; i++) {
if (a[i].start > lastEnd){
res++;
lastEnd=a[i].end;
}
}
return res;
}
每次选择剩下活动中最早结束的可获得最大相容组合。
可以用数学归纳法证明:
设A={a1,a2,a3,…,an}为所给的活动集合。集合按结束时间从小大大排列。
设B={b1,b2,…}为安排活动的最优解(元素的时间互不重叠)。集合也按结束时间从小大大排列。
若a1=b1,则B就是一个以贪心选择(选择最早结束的活动)开始的最优解。
若a1的结束时间小于b1的结束时间,设C= (B - b1) ∪ a1
由于a1的结束时间小于b1的结束时间,且B中活动是互为相容的,故C中的活动也是互为相容的。
又由于C中的活动个数与B(最优解)中活动个数相同,,故C也是最优的。
也就是说最优解C是一个以贪心选择活动a1开始的最优活动安排。
因此,证明了总存在一个以贪心选择开始的最优活动安排方案,也就是算法具有贪心选择性质。
求会场最小数
leetcode253——会议室 II
给定一个会议时间安排的数组,每个会议时间都会包括开始和结束的时间 [[s1,e1],[s2,e2],…] (si < ei),为避免会议冲突,同时要考虑充分利用会议室资源,请你计算至少需要多少间会议室,才能满足这些会议安排。
输入: [[0, 30],[5, 10],[15, 20]]
输出: 2
输入: [[7,10],[2,4]]
输出: 1
public int minMeetingRooms(int[][] intervals) {
if(intervals == null || intervals.length == 0)
return 0;
int[] start = new int[intervals.length];
int[] end = new int [intervals.length];
for(int i = 0; i < intervals.length; i ++) {
start[i] = intervals[i][0];
System.out.println(start[i]);
end[i] = intervals[i][1];
}
Arrays.sort(start);
Arrays.sort(end);
PriorityQueue<Integer> pq = new PriorityQueue<>(end.length);
pq.add(end[0]);
for(int i = 1; i < end.length; i ++) {
if(start[i] >= pq.peek())
pq.poll();
pq.add(end[i]);
}
return pq.size();
}