LeetCode进阶1029-贪心

概要

上一篇博客《LeetCode进阶944-贪心》,有朋友提出建议944对理解贪心算法并不具备很强的表明性。回顾了下上篇的内容,实际文中博主重点说明的是算法优化的小技巧,题解思路也仅仅只是简单的统计法,对贪心思想实际帮助确实不大。基于此博主已将上篇博客标题更正为《LeetCode进阶944-算法优化》(除订阅号因为微信公众平台的限制,标题暂时没法修改),而本篇将以leetcode1029为实例,讲解贪心算法思想。面试

闲聊

不知不觉,从开始发算法博客到现在已通过了半月,在这个过程当中其实也遇到过不少困难,也一度想过要放弃,深入体会到没有任何一件事情是能够简简单单敷衍过去的,特别能体会那些工做之余还能十年如一日坚持技术文章创做的做者们的不容易。不过尽管辛苦也有不少收获,好比精益求精,更追求更完美,又好比收获了不少技术之外的知识,认识了更多的朋友,视野也更加开阔。犹记得第一次投稿成功,第一次文章被大的专栏收录,第一次有人点赞,第一次有粉丝关注,甚至第一次某平台粉丝破百的时候心里的喜悦... 将来,但愿本身能把算法博客当成爱好一直写下去,也但愿能这些文章能给有须要的朋友带来实际的帮助。在后续博文推送过程当中,不排除也有些疏漏或者思惟理解上的误区,欢迎交流或批评指正。算法

原题

1029. Two City Scheduling

There are 2N people a company is planning to interview. The cost of flying the i-th person to city A is costs[i][0], and the cost of flying the i-th person to city B is costs[i][1].数组

Return the minimum cost to fly every person to a city such that exactly N people arrive in each city.bash

Example 1:微信

Input: [[10,20],[30,200],[400,50],[30,20]] Output: 110 Explanation: The first person goes to city A for a cost of 10. The second person goes to city A for a cost of 30. The third person goes to city B for a cost of 50. The fourth person goes to city B for a cost of 20.微信公众平台

The total minimum cost is 10 + 30 + 50 + 20 = 110 to have half the people interviewing in each city.优化

Note:ui

1 <= costs.length <= 100 It is guaranteed that costs.length is even. 1 <= costs[i][0], costs[i][1] <= 1000编码

1029. 面试安排(据题意命名)

公司安排2N我的参加面试。第i我的坐飞机飞到城市A的费用为costs[i][0],飞到城市B的费用为 costs[i][1]。spa

返回安排好每一个人都前往某城市面试的最低费用,A、B城市各有N我的参加。

例:

输入:[[10,20],[30,200],[400,50],[30,20]] 输出:110 说明: 第一我的前往 A 市,费用为 10。 第二我的前往 A 市,费用为 30。 第三我的前往 B 市,费用为 50。 第四我的前往B 市,费用为 20。

总花费最低为 10 + 30 + 50 + 20 = 110,两个城市各有一半人在面试。

提示:

1 <= costs.length <= 100 costs.length 为偶数 1 <= costs[i][0], costs[i][1] <= 1000

  • 本题在LeetCode上属于贪心算法分类下

题意分析

须要将2N我的分红两组,分别送往A、B城市面试,每一个人去A、B城市的费用已知,要保证总费用最少。凡事涉及最大最小值求和相关的题型,天然不难联想到贪心算法思想,贪心思想最典型的问题是“背包问题”,关于贪心思想须要注意的是,必定要确保“贪心”的思路正确即能拿到最优解,实践过程当中能够具体进行数值带入验证。

思路设计

根据题意,须要的最优解是花费最少的钱分别安排N我的前往A、B面试,每一个人前往A、B城市的花费有个价格差。能够这简单这么理解咱们能够统一计算出每一个人前往B城市比前往A城市须要多花的钱(也能够是前往A城市比前往B城市要多花的钱),而后进行排序,价格差最大的排名第一的人必然只能安排到A城市,这样能省下的成本费用最大。接着依次日后安排,排第二的人也只能安排到A城市,一直到安排了排第N的人到A城市,剩下的N我的因为前往B城市比前往A城市花费没那么高所有排到B城市。

伪代码:

一、新建一个大小和人数一致的int数组sort,用于保存每一个人前往B城市比前往A城市多花费的费用(注意费用能够是负数,负数等价理解花费更少);
     二、遍历costs花费数组,将差值记录在sort数组元素中;
       i.计算第i我的前往B和前往A的差值;
       ii.差值左移8位;
       iii.左移后加上当前在cost数组中的下标位置i;
     三、对差值sort数组进行排序;
     四、声明一个int变量min表示最小花费总和,循环遍历sort数组,遍历次数只需人数的一半costs.length/2;
       i.对于差值排名前N,即sort中最后的N我的,选择去A城市的花费,根据sort元素存储的在costs数组中的下标位置从costs数组中获取去A城市的花费;
       ii.对于差值排名后N,即sort中前N我的,选择去B城市的花费,根据sort元素存储的在costs数组中的下标位置从costs数组中获取去B城市的花费;
       iii.min累加全部总花费;
复制代码

编码实践

public int twoCitySchedCost(int[][] costs) {
		int sort[] = new int[costs.length];
		for (int i = 0; i < costs.length; ++i) {
			sort[i] = ((costs[i][1] - costs[i][0]) << 8) + i;
		}
		Arrays.sort(sort);
		int min = 0;
		for (int i = 0; i < sort.length / 2; ++i) {
			int index1 = sort[costs.length - 1 - i]  & 0xFF;
			int index2 = sort[i]  & 0xFF;
			min = min + costs[index1][0] + costs[index2][1];
		}
		return min;
	}
复制代码

彩蛋

观察上面实现代码会发如今sort数组中存储前往B和A城市int差价和在costs数组中下标位置时,使用了左移8位再加i的操做,这即是本文的彩蛋,全部彩蛋均会在后续推文中统一说明。

结语

本文重点在与列举1029实例展现对贪心思想的理解,思路相对简单易于理解,而且从提交结果能够看出贪心思想算法的实践代码效率已经击败了99%的算法,故对另外解法穷举法便不作详细说明,读者能够考虑本身使用穷举法进行实现。关于leetcode进阶系列博客,后续也会疏理出一篇比较系统的进阶大纲,敬请期待^_^

Alt

扫一扫 关注个人微信订阅号
相关文章
相关标签/搜索