原题链接: https://leetcode.com/problems/fair-candy-swap/
1. 题目介绍
Alice and Bob have candy bars of different sizes: A[i] is the size of the i-th bar of candy that Alice has, and B[j] is the size of the j-th bar of candy that Bob has.
Since they are friends, they would like to exchange one candy bar each so that after the exchange, they both have the same total amount of candy. (The total amount of candy a person has is the sum of the sizes of candy bars they have.)
Return an integer array ans where ans[0] is the size of the candy bar that Alice must exchange, and ans[1] is the size of the candy bar that Bob must exchange.
If there are multiple answers, you may return any one of them. It is guaranteed an answer exists.
Alice和Bob有不同大小的糖果棒。A[i] 是Alice的第i个糖果棒的大小,B[j] 是Bob的第j个糖果棒的大小。
因为Alice和Bob是朋友,为了获得总大小相同的糖果棒,他们决定交换1个糖果棒。
返回一个整数数组ans,ans[0] 是Alice必须交换的糖果棒大小,ans[1]是Bob必须交换的糖果棒大小。
如果有多种答案,你可以返回其中任何一个答案。题目保证有解。
Example 1:
Input: A = [1,1], B = [2,2]
Output: [1,2]
Example 2:
Input: A = [1,2], B = [2,3]
Output: [1,2]
Example 3:
Input: A = [2], B = [1,3]
Output: [2,3]
Example 4:
Input: A = [1,2,5], B = [2,4]
Output: [5,4]
Note:
1 <= A.length <= 10000
1 <= B.length <= 10000
1 <= A[i] <= 100000
1 <= B[i] <= 100000
It is guaranteed that Alice and Bob have different total amounts of candy.
It is guaranteed there exists an answer.
题目保证Alice和Bob的糖果总量是不同的,并且保证至少有一个解。
2. 解题思路
这是一道数学题目。
LeetCode的官方Solution已经解释的很好了,所以下面的方法源自Solution,有兴趣的读者可以直接看原文 https://leetcode.com/problems/fair-candy-swap/solution/
设:A数组的总和是SA,B数组的总和是SB,Alice要给Bob的糖果大小是X,Bob给Alice的糖果大小是Y。
于是可以得出如下公式:
S
A
−
X
+
Y
=
S
B
−
Y
+
X
S_{A} - X + Y = S_{B} -Y +X
SA−X+Y=SB−Y+X
将上述公式化简后可以得到:
Y
=
S
B
−
S
A
2
+
X
Y = \frac{S_{B}-S_{A}}{2} + X
Y=2SB−SA+X
如果令
t
=
S
B
−
S
A
2
t = \frac{S_{B}-S_{A}}{2}
t=2SB−SA,那么只需要在数组A中遍历
X
X
X,判断在数组B中
(
t
+
X
)
(t+X)
(t+X)是否存在即可。如果有,就返回
[
X
,
(
t
+
X
)
]
[X,(t+X)]
[X,(t+X)]。可以借助集合实现判断
(
t
+
X
)
(t+X)
(t+X)是否存在。
时间复杂度O(A.length+B.length).
空间复杂度O(B.length)
实现代码
class Solution {
public int[] fairCandySwap(int[] A, int[] B) {
int sa = 0;
int sb = 0;
Set<Integer> set = new HashSet<Integer>();
for (int i = 0; i<A.length;i++ ) {
sa+=A[i];
}
for (int i = 0; i<B.length;i++ ) {
sb+=B[i];
set.add(B[i]);
}
int t = (sb - sa) / 2;
for (int i = 0;i<A.length ;i++ ) {
if (set.contains(t + A[i] )) {
return new int []{ A[i] , t + A[i] };
}
}
return null;
}
}
3. 参考资料
我在写作本文的数学公式时,对于markdown下的数学公式表示方法不是很熟悉。于是参考了下面这篇文章:
Markdown公式编辑学习笔记 https://www.cnblogs.com/q735613050/p/7253073.html