最近我们开始练习贪心算法的题目,昨天因为卡在其中一道简单级别的题目上没能更新,今天补更,正好也借着卡的点分享下经验。关于贪心算法的介绍,如果想回顾,可以点上篇来看。
当时的介绍基本引用自诸多官方描述,这两天的相关题目做下来,对贪心算法的感觉却是这更归为一种设计解法的思想,有点拆分步骤或子问题,然后逐个击破的意思。而且这贪心算法的应用,跨度比较大的题目应用起来关联性又不大,还挺麻烦的。
刷这几道题目时,有些刻意练习贪心解法,比较耗时,之后还是要提高效率,先解题,再学习掌握更优算法。来看今儿的题目吧~
题目一
第 1029 题:两地调度
难度:简单
公司计划面试 2N 人。第 i 人飞往 A 市的费用为 costs[i][0],飞往 B 市的费用为 costs[i][1]。
返回将每个人都飞到某座城市的最低费用,要求每个城市都有 N 人抵达。
示例
输入:[[10,20],[30,200],[400,50],[30,20]]
输出:110
解释:
第一个人去 A 市,费用为 10。
第二个人去 A 市,费用为 30。
第三个人去 B 市,费用为 50。
第四个人去 B 市,费用为 20。
最低总费用为 10 + 30 + 50 + 20 = 110,每个城市都有一半的人在面试。
#来源:力扣(LeetCode)
#链接:https://leetcode-cn.com/problems/two-city-scheduling
题目分析
昨天我就是卡在了这道题,先说下我最初分析:既然要用贪心算法,这里有 2N 个人即 N 对人,那么我们一对对来分析,只要保证每新增一对,花费是最低的,那么最终也将是最低费用。
我们用一张图来展示题目中示例分析过程:
思路尝试
按照刚的设想,每增加一对人,我们先对他们俩的费用分析,其中一个分配去 A、另一个去 B。
但这时,要去 A 的人还要和已经被安排去 B 的所有人来进行比较,看有没有更便宜的组合来对调;同理,要去 B 的这位也要在被安排去 A 的人里进行比较一番,若有更便宜组合则对调,没有的话就按此分配。
这样,每一对人,我们都拿到了最低的分配费用,那么累计 N 对后的 2N 个人,其价格也是最低的。
代码实现
class Solution:
def twoCitySchedCost(self, costs: List[List[int]]) -> int:
# 分配去 A 的名单
list_A=[]
# 分配去 B 的名单
list_B=[]
# 总人数
length = len(costs)
# 人数分成 n 对
n = length//2
# 是否要与分配好的人对调
swap = False
# 定义一个判断目前去AB的组合是否价格最优
def check_AB(p,q):
# 若 p 去 A、q 去 B 的价格 低于 q 去 A、p 去 B 的价格
if costs[p][0]+costs[q][1]