【哈希表】LeetCode 888. 公平的糖果棒交换

888. 公平的糖果棒交换


题目来源:力扣(LeetCode)https://leetcode-cn.com/problems/fair-candy-swap/

题目


爱丽丝和鲍勃有不同大小的糖果棒:A[i] 是爱丽丝拥有的第 i 根糖果棒的大小,B[j] 是鲍勃拥有的第 j 根糖果棒的大小。

因为他们是朋友,所以他们想交换一根糖果棒,这样交换后,他们都有相同的糖果总量。(一个人拥有的糖果总量是他们拥有的糖果棒大小的总和。)

返回一个整数数组 ans,其中 ans[0] 是爱丽丝必须交换的糖果棒的大小,ans[1] 是 Bob 必须交换的糖果棒的大小。

如果有多个答案,你可以返回其中任何一个。保证答案存在。

示例 1:

输入:A = [1,1], B = [2,2]
输出:[1,2]

示例 2:

输入:A = [1,2], B = [2,3]
输出:[1,2]

示例 3:

输入:A = [2], B = [1,3]
输出:[2,3]

示例 4:

输入:A = [1,2,5], B = [2,4]
输出:[5,4]

提示:

  • 1 <= A.length <= 10000
  • 1 <= B.length <= 10000
  • 1 <= A[i] <= 100000
  • 1 <= B[i] <= 100000
  • 保证爱丽丝与鲍勃的糖果总量不同。
  • 答案肯定存在。

解题思路


思路:哈希表

这里,先看题目最后的提示部分,【保证爱丽丝与鲍勃的糖果总量不同】和【答案肯定存在】,即是说题目一定有解,要使得两人手中糖果总量相等,必然存在要交换的情况。

题目最后提醒,若存在多个答案时,返回其中一个即可。所以我们在查找的过程中,只要找到符合条件的情形,即可返回结果。

现在先审题,注意其中的参数:

  • A A A:代表 A l i c e Alice Alice 手中拥有的糖果棒;
  • B B B :代表 B o b Bob Bob 手中拥有的糖果棒;
  • A [ i ] A[i] A[i] :表示 A l i c e Alice Alice 手中第 i i i 根糖果棒的大小;
  • B [ j ] B[j] B[j] :表示 B o b Bob Bob 手中第 j j j 根糖果棒的大小。

题目设定:

  • A l i c e Alice Alice B o b Bob Bob 会交换各自手中的某根糖果棒,使得交换后两人的糖果总量相同。

糖果总量:指手中糖果棒大小的总和。

最终题目所求:

  • 返回一个整数数组 a n s ans ans,其中 a n s [ 0 ] ans[0] ans[0] 表示 A l i c e Alice Alice 交换出去糖果棒的大小, a n s [ 1 ] ans[1] ans[1] 表示 B o b Bob Bob 交换出去糖果棒的大小。

首先,我们先注意交换后的结果,两人手中最终的糖果总量是相等的。

假设 s u m _ A sum\_A sum_A A l i c e Alice Alice 原本手中糖果总量, s u m _ B sum\_B sum_B 表示 B o b Bob Bob 原本手中糖果总量。而 a a a 表示 A l i c e Alice Alice 交换出去的糖果棒大小, b b b 表示 B o b Bob Bob 交换出去的糖果棒大小。因为最终交换后,两人的糖果总量是相等的,那么就有如下等式:
s u m _ A − a + b = s u m _ B − b + a sum\_A - a + b = sum\_B - b + a sum_Aa+b=sum_Bb+a
进行简化:
s u m _ A − a + b = s u m _ B − b + a 2 × a = s u m _ A − s u m _ B + 2 × b a = ( s u m _ A − s u m _ B ) 2 + b \begin{aligned} sum\_A - a + b & = sum\_B - b + a \\ 2 \times a & = sum\_A - sum\_B + 2 \times b \\ a &= \frac{(sum\_A - sum\_B)}{2} + b \end{aligned} sum_Aa+b2×aa=sum_Bb+a=sum_Asum_B+2×b=2(sum_Asum_B)+b
d e l t a = ( s u m _ A − s u m _ B ) 2 delta = \frac{(sum\_A - sum\_B)}{2} delta=2(sum_Asum_B),那么

当数组 B B B 中存在一个数 b b b,使得 b + d e l t a b + delta b+delta 的和 a a a 存在于数组 A A A 中,那么此时 [ a , b ] [a, b] [a,b] 就是一组解。

因为需要查找 a a a 是否存在于 A A A 中,这里将数组 A A A 的元素存入哈希表中。然后遍历数组 B B B,将每个元素代入上面等式,检查 a a a 是否存在于 A A A 中。

具体的代码实现如下。

class Solution:
    def fairCandySwap(self, A: List[int], B: List[int]) -> List[int]:
        # 先求 A、B 的总量
        sum_A = sum(A)
        sum_B = sum(B)
        # 根据文章得到的公式,先求 delta
        delta = (sum_A - sum_B) // 2
        
        # 将数组 A 元素存入哈希表
        A = set(A)
        # 遍历 B,进行查找
        for b in B:
            a = b + delta
            if a in A:
                return [a, b]

欢迎关注


公众号 【书所集录】


如有错误,烦请指出,欢迎指点交流。若觉得写得还不错,麻烦点个赞,谢谢。

你可能感兴趣的:(LeetCode,leetcode,算法,哈希表,python)