活动选择问题是经典的贪心算法问题,目标是在一系列活动中选择尽可能多的互不冲突的活动。每个活动都有一个开始时间和结束时间,选择的活动不能有时间上的重叠。通常假设活动已经按照结束时间排序。
以下是活动选择问题的一个简单Java实现,采用贪心算法来选择最大兼容活动子集:
import java.util.Arrays;
import java.util.Comparator;
public class ActivitySelection {
public static class Activity {
int start;
int finish;
public Activity(int start, int finish) {
this.start = start;
this.finish = finish;
}
}
// 活动选择的贪心算法实现
public static void selectActivities(Activity[] activities) {
// 按照活动的结束时间对活动进行排序
Arrays.sort(activities, Comparator.comparingInt(a -> a.finish));
// 第一个活动总是被选中
int i = 0;
System.out.println("Selected activities:");
System.out.println("(" + activities[i].start + ", " + activities[i].finish + ")");
// 对剩余的活动进行迭代
for (int j = 1; j < activities.length; j++) {
// 如果当前活动的开始时间大于或等于前一个选中活动的结束时间,则选择当前活动
if (activities[j].start >= activities[i].finish) {
System.out.println("(" + activities[j].start + ", " + activities[j].finish + ")");
i = j; // 更新最近一次选中的活动索引
}
}
}
public static void main(String[] args) {
Activity[] activities = {
new Activity(1, 2),
new Activity(3, 4),
new Activity(0, 6),
new Activity(5, 7),
new Activity(8, 9),
new Activity(5, 9)
};
selectActivities(activities);
}
}
在这个Java程序中:
- 定义了一个
Activity
类用来表示一个活动,它包含开始时间start
和结束时间finish
。 selectActivities
方法接收一个Activity
数组作为输入,并且已经按照活动结束时间排序。这个方法选择出最大的兼容活动子集并打印出来。- 首先选择第一个活动,因为它结束得最早,然后遍历剩下的活动,如果当前活动的开始时间大于等于上一次选择的活动的结束时间,则选择这个活动。
这个实现假定输入的活动已经根据结束时间升序排列,这是贪心算法正常工作的关键前提。如果活动没有预先排序,你需要在selectActivities
方法的开始进行排序(如代码中所示)。
活动选择问题的贪心算法时间复杂度为O(n*log(n)),如果输入活动已经按结束时间排序,则复杂度为O(n),其中 n 是活动的数量。