公司面试人员城市分配| 豆包MarsCode AI 刷题

78 阅读3分钟

问题描述

公司计划面试 2n 人,并需要将每个人分配到两个城市中的一个。每个人飞往城市 A 或城市 B 的费用不同,具体体现在数组 costs 中,其中 costs[i] = [aCosti, bCosti] 代表第 i 个人飞往城市 A 和城市 B 的费用。你需要帮助公司计算将 2n 个人分配到两个城市的最低费用,要求每个城市都有 n 个人到达。

问题分析

每个人有两个选择:飞往城市 A 或者飞往城市 B。每个选择的费用都不同,因此我们需要合理分配这 2n 个人到两个城市,保证每个城市有 n 个人,并且总费用最小。

解题思路

  1. 计算费用差异:每个人飞往城市 A 或 B 的费用分别是 costs[i][0]costs[i][1]。计算每个人飞往城市 A 和 B 的费用差异:diff[i] = costs[i][0] - costs[i][1]。如果差异是正的,说明飞往城市 A 更贵,反之则说明飞往城市 B 更贵。
  2. 排序:我们希望将费用差异小的人分配到两个城市,这样可以避免大额的费用差异影响总费用。因此,我们可以根据每个人的费用差异进行排序,差异小的优先处理。
  3. 分配人员:排序后,前 n 个费用差异较小的人飞往城市 A,剩余的 n 个人飞往城市 B。这样,尽量让费用差异大的人员选择费用较低的城市。
  4. 计算总费用:根据排序后的顺序,计算每个人飞往相应城市的费用并求和。

代码实现

import java.util.Arrays;

public class Main {
    public static int solution(int[][] costs) {
        int n = costs.length / 2;
        
        // 计算费用差异并排序
        Arrays.sort(costs, (a, b) -> (a[0] - a[1]) - (b[0] - b[1]));
        
        int totalCost = 0;
        
        // 前 n 个分配到城市 A
        for (int i = 0; i < n; i++) {
            totalCost += costs[i][0];  // 选择飞往城市 A 的费用
        }
        
        // 后 n 个分配到城市 B
        for (int i = n; i < 2 * n; i++) {
            totalCost += costs[i][1];  // 选择飞往城市 B 的费用
        }
        
        return totalCost;
    }

    public static void main(String[] args) {
        int[][] costs1 = {{10, 20}, {30, 20}, {40, 50}, {30, 20}};
        int[][] costs2 = {{59, 77}, {48, 54}, {96, 66}, {18, 19}};
        int[][] costs3 = {{15, 53}, {41, 73}, {57, 79}, {34, 89}};

        System.out.println(solution(costs1) == 90);  // 输出: true
        System.out.println(solution(costs2) == 192); // 输出: true
        System.out.println(solution(costs3) == 201); // 输出: true
    }
}

复杂度分析

  • 时间复杂度:排序的时间复杂度为 O(n log n),遍历一次数组计算总费用的时间复杂度是 O(n)。因此,总时间复杂度为 O(n log n)
  • 空间复杂度:主要使用了输入数组的空间,空间复杂度是 O(1),除了输入数据外没有额外的空间使用。

总结

该问题的关键在于通过计算每个人的费用差异并进行排序,优先选择费用差异较小的人进行分配,从而达到最小化总费用的目的。通过这种贪心策略,可以高效地求解问题。