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_A−a+b=sum_B−b+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_A−a+b2×aa=sum_B−b+a=sum_A−sum_B+2×b=2(sum_A−sum_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_A−sum_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]
欢迎关注
公众号 【书所集录】
如有错误,烦请指出,欢迎指点交流。若觉得写得还不错,麻烦点个赞👍,谢谢。