leetcode 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.
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:
1 <= costs.length <= 100
- It is guaranteed that
costs.length
is even. 1 <= costs[i][0], costs[i][1] <= 1000
题目大意:
公司计划面试 2N 人。第 i 人飞往 A 市的费用为 costs[i][0],飞往 B 市的费用为 costs[i][1]。
返回将每个人都飞到某座城市的最低费用,要求每个城市都有 N 人抵达。
思路:采用贪心算法,按照每个人到A城市的费用从小到大排序,去前N个到A城市,虽然这个N个人到A城市的费用最低,但另外N个人到达B城市的费用大概率不是最低,导致加起来的总费用不是最低。所以应该联合起来考虑。每一个人都必须去一个城市,如何确定他应该去A还是B呢?考虑他去A,相对于去B城市能省多少钱,省的越多,最后总费用就越低。
以样例 [[10,20],[30,200],[400,50],[30,20]]为例,
p1: [10,20] -> 10-20=-10
p2: [30, 200] -> 30-200=-170
p3:[400,50] -> 400-50 = 350
p4:[30,20] -> 30-20 = 10
基于差值从小到大排序:-170,-10,10, 350 -> [[30,200],[10,20],[30,20],[400,50]],即排序后的前两个人选城市A,后两个人选城市B。
1 class Solution { 2 public: 3 static bool cmp(const vector<int> &a, const vector<int> &b) { 4 return (a[0] - a[1]) < (b[0] - b[1]); 5 } 6 int twoCitySchedCost(vector<vector<int>>& costs) { 7 int N = costs.size() / 2; 8 sort(costs.begin(), costs.end(), cmp); 9 int cost = 0; 10 for (int i = 0; i < N; ++i) { 11 cost += costs[i][0]; 12 cost += costs[i + N][1]; 13 } 14 return cost; 15 } 16 };
时间复杂度:$O(nlogn)$
空间复杂度:$O(1)$
从另一个视角看,所有人都去A城市,需要安排N个人转到B城市,我们找到相较于去A城市,去B城市最省的N个人:
所有人去A城市的总费用为10+30+400+30 = 470, 按照差值排序后,最后2个人分别能省350、10,因此安排这个两个人去B城市,最后总费用为470-350-10=110
1 class Solution { 2 public: 3 int twoCitySchedCost(vector<vector<int>>& costs) { 4 int N = costs.size() / 2; 5 vector<int> diff(costs.size(), 0); 6 int sum = 0; 7 for (int i = 0; i < costs.size(); ++i) { 8 sum += costs[i][0]; 9 diff[i] = costs[i][1] - costs[i][0]; 10 } 11 sort(diff.begin(), diff.end());//默认从小到大排序,所以计算差值的时候用costs[i][1] - costs[i][0] 12 for (int i = 0; i < N; ++i) { 13 sum += diff[i]; 14 } 15 return sum; 16 } 17 };
时间复杂度:$O(nlogn)$
空间复杂度:$O(n)$