列表

详情


6345. 重排水果

你有两个果篮,每个果篮中有 n 个水果。给你两个下标从 0 开始的整数数组 basket1basket2 ,用以表示两个果篮中每个水果的成本。

你希望两个果篮相等。为此,可以根据需要多次执行下述操作:

根据果篮中水果的成本进行排序,如果排序后结果完全相同,则认为两个果篮相等。

返回使两个果篮相等的最小交换成本,如果无法使两个果篮相等,则返回 -1

 

示例 1:

输入:basket1 = [4,2,2,2], basket2 = [1,4,1,2]
输出:1
解释:交换 basket1 中下标为 1 的水果和 basket2 中下标为 0 的水果,交换的成本为 1 。此时,basket1 = [4,1,2,2] 且 basket2 = [2,4,1,2] 。重排两个数组,发现二者相等。

示例 2:

输入:basket1 = [2,3,4,1], basket2 = [3,2,5,1]
输出:-1
解释:可以证明无法使两个果篮相等。

 

提示:

原站题解

去查看

上次编辑到这里,代码来自缓存 点击恢复默认模板
class Solution { public: long long minCost(vector<int>& basket1, vector<int>& basket2) { } };

golang 解法, 执行用时: 168 ms, 内存消耗: 13.2 MB, 提交时间: 2023-02-06 10:39:36

func minCost(basket1, basket2 []int) (ans int64) {
	cnt := map[int]int{}
	for i, x := range basket1 {
		cnt[x]++
		cnt[basket2[i]]--
	}

	mn, a := math.MaxInt, []int{}
	for x, c := range cnt {
		if c%2 != 0 {
			return -1
		}
		mn = min(mn, x)
		for c = abs(c) / 2; c > 0; c-- {
			a = append(a, x)
		}
	}

	sort.Ints(a) // 也可以用快速选择
	for _, x := range a[:len(a)/2] {
		ans += int64(min(x, mn*2))
	}
	return
}

func abs(x int) int { if x < 0 { return -x }; return x }
func min(a, b int) int { if b < a { return b }; return a }

cpp 解法, 执行用时: 160 ms, 内存消耗: 83.9 MB, 提交时间: 2023-02-06 10:39:06

class Solution {
public:
    long long minCost(vector<int> &basket1, vector<int> &basket2) {
        unordered_map<int, int> cnt;
        for (int i = 0; i < basket1.size(); ++i) {
            ++cnt[basket1[i]];
            --cnt[basket2[i]];
        }

        int mn = INT_MAX;
        vector<int> a;
        for (auto [x, c] : cnt) {
            if (c % 2) return -1;
            mn = min(mn, x);
            for (c = abs(c) / 2; c > 0; --c)
                a.push_back(x);
        }

        long ans = 0;
        nth_element(a.begin(), a.begin() + a.size() / 2, a.end()); // 快速选择
        for (int i = 0; i < a.size() / 2; ++i)
            ans += min(a[i], mn * 2);
        return ans;
    }
};

java 解法, 执行用时: 34 ms, 内存消耗: 60.6 MB, 提交时间: 2023-02-06 10:38:45

class Solution {
    public long minCost(int[] basket1, int[] basket2) {
        var cnt = new HashMap<Integer, Integer>();
        for (int i = 0; i < basket1.length; ++i) {
            cnt.merge(basket1[i], 1, Integer::sum);
            cnt.merge(basket2[i], -1, Integer::sum);
        }

        int mn = Integer.MAX_VALUE;
        var a = new ArrayList<Integer>();
        for (var e : cnt.entrySet()) {
            int x = e.getKey(), c = e.getValue();
            if (c % 2 != 0) return -1;
            mn = Math.min(mn, x);
            for (c = Math.abs(c) / 2; c > 0; --c)
                a.add(x);
        }

        long ans = 0;
        a.sort((x, y) -> x - y); // 也可以用快速选择
        for (int i = 0; i < a.size() / 2; ++i)
            ans += Math.min(a.get(i), mn * 2);
        return ans;
    }
}

python3 解法, 执行用时: 216 ms, 内存消耗: 36.9 MB, 提交时间: 2023-02-06 10:38:26

'''
贪心+构造,把两个篮子里最小的数作为中介工具
'''
class Solution:
    def minCost(self, basket1: List[int], basket2: List[int]) -> int:
        cnt = Counter()
        for x, y in zip(basket1, basket2):
            cnt[x] += 1
            cnt[y] -= 1
        mn = min(cnt)
        a = []
        for x, c in cnt.items():
            if c % 2: return -1
            a.extend([x] * (abs(c) // 2))
        a.sort()  # 也可以用快速选择
        return sum(min(x, mn * 2) for x in a[:len(a) // 2])

上一题