leetcode
leetcode 801 ~ 850
公平的糖果交换

公平的糖果交换

难度:

标签:

题目描述

代码结果

运行时间: 55 ms, 内存: 17.9 MB


/*
 * 思路:
 * 1. 计算爱丽丝和鲍勃各自的糖果总数。
 * 2. 计算需要交换的糖果数目差 diff = (aliceSum - bobSum) / 2。
 * 3. 用一个集合来存储爱丽丝所有糖果的数目。
 * 4. 使用 Java Stream 遍历鲍勃的糖果数目,检查是否存在爱丽丝的糖果数目满足 aliceCandy - bobCandy = diff。
 * 5. 找到符合条件的糖果数目,返回结果。
 */
import java.util.*;
import java.util.stream.*;

public class CandySwapStream {
    public int[] fairCandySwap(int[] aliceSizes, int[] bobSizes) {
        int aliceSum = Arrays.stream(aliceSizes).sum();
        int bobSum = Arrays.stream(bobSizes).sum();
        int diff = (aliceSum - bobSum) / 2;

        Set<Integer> aliceSet = Arrays.stream(aliceSizes).boxed().collect(Collectors.toSet());

        return Arrays.stream(bobSizes)
                .filter(candy -> aliceSet.contains(candy + diff))
                .mapToObj(candy -> new int[]{candy + diff, candy})
                .findFirst()
                .orElse(new int[0]);  // 实际上这里不会到达,题目保证有答案
    }
}

解释

方法:

题解的思路是通过找到一个公式来确定爱丽丝和鲍勃需要交换的糖果盒数量,使得交换后两人的糖果总量相等。首先计算出爱丽丝和鲍勃各自糖果的总数量sumA和sumB。通过计算delta = (sumA - sumB) / 2,得到爱丽丝需要比鲍勃多交换的糖果数量。通过遍历鲍勃的糖果数组,查找一个糖果数b,使得a = b + delta存在于爱丽丝的糖果集合中,即找到一个满足条件的(a, b)对,返回这个对即为答案。

时间复杂度:

O(m + n)

空间复杂度:

O(m)

代码细节讲解

🦆
为什么题解中的delta使用的是(sumA - sumB) // 2来计算,这样的计算逻辑是基于什么理论或者规则?
这个计算逻辑基于平衡交换的原则。设交换后两人的糖果总量相等,因此有等式:sumA - a + b = sumB - b + a。整理得2a - 2b = sumA - sumB,即a - b = (sumA - sumB) / 2。这里的delta = (sumA - sumB) / 2表示爱丽丝和鲍勃在达到平衡状态时,糖果数差的一半,即爱丽丝需要额外给出的糖果数与鲍勃需要增加的糖果数之差。
🦆
在查找满足条件的(a, b)对时,为什么优先遍历bobSizes而不是aliceSizes,这样的选择对算法的效率有什么影响?
选择遍历bobSizes主要是因为我们需要找到满足a = b + delta的对应关系,这里delta是通过sumA和sumB计算得到的固定值。通过先固定b,然后计算a = b + delta可以直接判断a是否存在于aliceSizes的集合中,这样的查找是O(1)的时间复杂度,使得整体算法效率为O(n),其中n是bobSizes的长度。如果反过来遍历aliceSizes,对于每个a,我们需要计算b = a - delta并检查b是否在bobSizes中,这同样是高效的,因此遍历哪一个数组主要取决于实现细节和数组长度,没有根本性的效率差异。
🦆
如果aliceSizes和bobSizes中有重复的糖果数,会对算法的输出结果产生什么样的影响?
如果aliceSizes和bobSizes中有重复的糖果数,不会影响算法的正确性或输出结果。算法寻找的是一对满足特定条件的(a, b),即使有重复的糖果数,只要找到任意一对满足a = b + delta的糖果数对即可。算法只需返回找到的第一对满足条件的糖果对,因此重复的糖果数不会导致输出结果有错误或多余的对。
🦆
题解中使用了整数除法//来计算delta,如果sumA和sumB的差是奇数会发生什么?题目是否保证了sumA和sumB的差总是偶数?
如果sumA和sumB的差是奇数,则使用整数除法//计算delta会导致结果向下取整,从而使delta不准确,因为a和b必须是整数。这种情况下,题解中的方法将无法找到正确的(a, b)对,因为不存在整数a和b满足a - b等于一个非整数。题目的描述中并没有明确保证sumA和sumB的差总是偶数,这是一个需要额外验证或者题目假设需要明确的地方。如果不保证这一点,算法需要额外的逻辑来处理这种情况或者在题目条件中明确说明。

相关问题