zoukankan      html  css  js  c++  java
  • 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. 1 <= costs.length <= 100
    2. It is guaranteed that costs.length is even.
    3. 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)$

  • 相关阅读:
    使用批处理查找某个文件夹及其子文件夹(递归地)中存在的空文件夹
    pl/sql连接oracle
    JSON对象转换成url参数
    创建maven工程
    线程同步
    java.lang.Object 的 wait 和 notify方法,及关键字 synchronized的作用
    Thread操作
    java.lang.io包的使用
    用程序打印汉字
    java程序员应该熟练掌握的技术
  • 原文地址:https://www.cnblogs.com/qinduanyinghua/p/13043050.html
Copyright © 2011-2022 走看看