左神算法课第7章_前缀树和贪心算法

一、前缀树

在这里插入图片描述

经典的两种查询:pass代表有几个字符串以当前节点为前缀,end代表某个字符串出现了几次
删除的操作:沿途的P值减减,最后一个end值减减

二、贪心算法

在这里插入图片描述

针对每一个题目,如果每次都去证明自己所想的策略能不能行得通,是很慢很繁琐也很容易出错的,很难用严格的数学证明,考场上不适用。
在这里插入图片描述
贪心算法的笔试,首先要把暴力的方法写熟了,变成模板,再写对数器
在这里插入图片描述
贪心策略,堆和排序是最常用的两个技巧。
最重要的事情是写模板,然后去了解各种各样的贪心策略是啥,贪心算法是一个比较难解决的事情。笔试出现的概率很大,但是占比不大。面试几乎不会考,因为考察不了coding能力。面试考察的题目是要求有区分度的,不同的人会有不同的策略。

1、会议室安排问题(1:03)

在这里插入图片描述

结束时间早的会议先安排

public class Code04_BestArrange {

	public static class Program {//每个会议都有起始时间和结束时间
		public int start;
		public int end;

		public Program(int start, int end) {
			this.start = start;
			this.end = end;
		}
	}
//写个比较器来比较谁的结束时间更早
	public static class ProgramComparator implements Comparator<Program> {

		@Override
		public int compare(Program o1, Program o2) {
			return o1.end - o2.end;
		}

	}

	public static int bestArrange(Program[] programs, int start) {
		Arrays.sort(programs, new ProgramComparator());//按照结束时间排序
		int result = 0;
		for (int i = 0; i < programs.length; i++) {
			if (start <= programs[i].start) {
				result++;
				start = programs[i].end;
			}
		}
		return result;
	}

	public static void main(String[] args) {

	}

}
2、排序字符串使得整体字典序最低(1:19)

在这里插入图片描述
将原来直接比较字典序的方法替换成先组合再比较组合的字典序的方法

public class Code02_LowestLexicography {

	public static class MyComparator implements Comparator<String> {
		@Override
		public int compare(String a, String b) {
			return (a + b).compareTo(b + a);//组合的字典序比较
		}
	}

	public static String lowestString(String[] strs) {
		if (strs == null || strs.length == 0) {
			return "";
		}
		Arrays.sort(strs, new MyComparator());
		String res = "";
		for (int i = 0; i < strs.length; i++) {
			res += strs[i];
		}
		return res;
	}

	public static void main(String[] args) {
		String[] strs1 = { "jibw", "ji", "jp", "bw", "jibw" };
		System.out.println(lowestString(strs1));

		String[] strs2 = { "ba", "b" };
		System.out.println(lowestString(strs2));

	}

}

3、切金条

在这里插入图片描述
典型的哈夫曼编码问题。上来先把所有的数放到小根堆,每次弹出两个数做结合,再扔进小根堆,再弹出两个数做结合,这样循环。

	public static int lessMoney(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;
	}
4、挣钱(2:01)

在这里插入图片描述

	public static int findMaximizedCapital(int k, int W, int[] Profits, int[] Capital) {
		Node[] nodes = new Node[Profits.length];
		for (int i = 0; i < Profits.length; i++) {
			nodes[i] = new Node(Profits[i], Capital[i]);
		}

		PriorityQueue<Node> minCostQ = new PriorityQueue<>(new MinCostComparator());
		PriorityQueue<Node> maxProfitQ = new PriorityQueue<>(new MaxProfitComparator());
		for (int i = 0; i < nodes.length; i++) {
			minCostQ.add(nodes[i]);
		}
		for (int i = 0; i < k; i++) {
			while (!minCostQ.isEmpty() && minCostQ.peek().c <= W) {
				maxProfitQ.add(minCostQ.poll());
			}
			if (maxProfitQ.isEmpty()) {
				return W;
			}
			W += maxProfitQ.poll().p;
		}
		return W;
	}
5、堆的应用(2:17)

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值