LeetCode.888 公平的糖果交换

378 阅读2分钟

「这是我参与2022首次更文挑战的第4天,活动详情查看:2022首次更文挑战」。

题目描述:

888. 公平的糖果交换 - 力扣(LeetCode) (leetcode-cn.com)

爱丽丝和鲍勃拥有不同总数量的糖果。给你两个数组 aliceSizesbobSizesaliceSizes[i] 是爱丽丝拥有的第 i 盒糖果中的糖果数量,bobSizes[j] 是鲍勃拥有的第 j 盒糖果中的糖果数量。

两人想要互相交换一盒糖果,这样在交换之后,他们就可以拥有相同总数量的糖果。一个人拥有的糖果总数量是他们每盒糖果数量的总和。

返回一个整数数组 answer,其中 answer[0] 是爱丽丝必须交换的糖果盒中的糖果的数目,answer[1] 是鲍勃必须交换的糖果盒中的糖果的数目。如果存在多个答案,你可以返回其中 任何一个 。题目测试用例保证存在与输入对应的答案。

示例一

输入: aliceSizes = [1,1], bobSizes = [2,2]
输出: [1,2]

示例二

输入: aliceSizes = [1,2], bobSizes = [2,3]
输出: [1,2]

示例三

输入: aliceSizes = [2], bobSizes = [1,3]
输出: [2,3]

示例四

输入: aliceSizes = [1,2,5], bobSizes = [2,4]
输出: [5,4]

提示:

  • 1 <= aliceSizes.length, bobSizes.length <= 10^4
  • 1 <= aliceSizes[i], bobSizes[j] <= 10^5
  • 爱丽丝和鲍勃的糖果总数量不同。
  • 题目数据保证对于给定的输入至少存在一个有效答案。

思路分析

哈希表

这个利用简单的数学知识即可简单解答。

我们假设爱丽丝的糖果棒的总大小为 sumA\textit{sumA},鲍勃的糖果棒的总大小为 sumB\textit{sumB}

假设有一组答案为 {x,y}\{x,y\},即爱丽丝的大小为 xx 的糖果棒与鲍勃的大小为 yy 的糖果棒交换,则有如下等式:

sumAx+y=sumB+xy\textit{sumA} - x + y = \textit{sumB} + x - y

化简,得:

x=y+sumAsumB2x = y + \frac{\textit{sumA} - \textit{sumB}}{2}

得到公式之后就很简单了,我们只需要遍历数组即可。

当然还有优化的解法,也就是利用位图。

AC代码

class Solution {
    fun fairCandySwap(aliceSizes: IntArray, bobSizes: IntArray): IntArray {
        val delta = (aliceSizes.sum() - bobSizes.sum()) shr 1
        val flag = BooleanArray(100001)
        bobSizes.forEach { flag[it] = true }
        for (a in aliceSizes) {
            val b = a - delta
            if (b in 1..100001 && flag[b]) {
                return intArrayOf(a, b)
            }
        }
        return intArrayOf()
    }
}

总结

此题还可以用二分法优化下。

参考

公平的糖果交换 - 公平的糖果交换 - 力扣(LeetCode) (leetcode-cn.com)

是不是没什么人用kotlin写算法的 - 公平的糖果交换 - 力扣(LeetCode) (leetcode-cn.com)

888. 公平的糖果棒交换,比官方题解还要好的解法 - 公平的糖果交换 - 力扣(LeetCode) (leetcode-cn.com)