一 、贪心算法的解题套路实战 贪心的算法和排序和堆有关
1.1 描述
一些项目要占用一个会议室宣讲,会议室不能同时容纳两个项目的宣讲。
给你每一个项目开始的时间和结束的时间
你来安排宣讲的日程,要求会议室进行的宣讲的场次最多。
返回最多的宣讲场次。
1.2 分析 在绝对环境下选择最优解
贪心 先按会议结束时间排序,然后在在数组里面找,先以开始时间为0,找第一个会议结束的时间更新会议下一个可以开始的时间为当前这个会议的结束时间,那么下一个会议可以开始的时间要大于前面那个结束的时间
1.3 代码
// 会议的开始时间和结束时间,都是数值,不会 < 0
public static int bestArrange2(Program[] programs) {
Arrays.sort(programs, new ProgramComparator());
int timeLine = 0;//会议的默认结束时间
int result = 0;
// 依次遍历每一个会议,结束时间早的会议先遍历
//比如上一个会议的结束时间比下一个会议的开始时间小,那么下一个会议就可以在上一个会议结束的时候开始
for (int i = 0; i < programs.length; i++) {
if (timeLine <= programs[i].start) {
result++;
timeLine = programs[i].end;
}
}
return result;
}
//比较器
public static class ProgramComparator implements Comparator<Program> {
@Override
public int compare(Program o1, Program o2) {
return o1.end - o2.end;
}
}
二 、 贪心算法的解题套路实战
2.1 描述
一块金条切成两半,是需要花费和长度数值一样的铜板的。
比如长度为20的金条,不管怎么切,都要花费20个铜板。 一群人想整分整块金条,怎么分最省铜板?
例如,给定数组{10,20,30},代表一共三个人,整块金条长度为60,金条要分成10,20,30三个部分。
如果先把长度60的金条分成10和50,花费60;
再把长度50的金条分成20和30,花费50;
一共花费110铜板。
但如果先把长度60的金条分成30和30,花费60;再把长度30金条分成10和20, 花费30;一共花费90铜板。
输入一个数组,返回分割的最小代价。
2.2 分析贪心算法解决输入一个数组返回金条分割的最小代价既哈夫曼树
流程 使用小跟堆,每次从堆里面弹出两个树合完放入小根堆,等堆排好序后又弹出两个树,当小跟堆里面只剩一个树的时候停止,形成如下的树的方案就是最右方案,代价就是圈里面的值加起来-这就是在创建一棵哈夫曼树!
2.3 代码
public static int lessMoney2(int[] arr) {
PriorityQueue<Integer> pQ = new PriorityQueue<>();
for (int i = 0; i < arr.length; i++) {
pQ.add(arr[i]);
}
int sum = 0;
int cur = 0;
while (pQ.size() > 1) {
cur = pQ.poll() + pQ.poll();
sum += cur;
pQ.add(cur);
}
return sum;
}