爱丽丝和鲍勃拥有不同总数量的糖果。给你两个数组 aliceSizes 和 bobSizes ,aliceSizes[i] 是爱丽丝拥有的第 i 盒糖果中的糖果数量,bobSizes[j] 是鲍勃拥有的第 j 盒糖果中的糖果数量。
两人想要互相交换一盒糖果,这样在交换之后,他们就可以拥有相同总数量的糖果。一个人拥有的糖果总数量是他们每盒糖果数量的总和。
返回一个整数数组 answer,其中 answer[0] 是爱丽丝必须交换的糖果盒中的糖果的数目,answer[1] 是鲍勃必须交换的糖果盒中的糖果的数目。如果存在多个答案,你可以返回其中 任何一个 。题目测试用例保证存在与输入对应的答案。
示例 1:
输入:aliceSizes = [1,1], bobSizes = [2,2]
输出:[1,2]
示例 2:
输入:aliceSizes = [1,2], bobSizes = [2,3]
输出:[1,2]
示例 3:
输入:aliceSizes = [2], bobSizes = [1,3]
输出:[2,3]
示例 4:
输入:aliceSizes = [1,2,5], bobSizes = [2,4]
输出:[5,4]
提示:
1 <= aliceSizes.length, bobSizes.length <= 104
1 <= aliceSizes[i], bobSizes[j] <= 105
爱丽丝和鲍勃的糖果总数量不同。
题目数据保证对于给定的输入至少存在一个有效答案。
方法一:哈希表
思路及算法
记爱丽丝的糖果棒的总大小为 sumA\textit{sumA}sumA,鲍勃的糖果棒的总大小为 sumB\textit{sumB}sumB。设答案为 {x,y}\{x,y\}{x,y},即爱丽丝的大小为 xxx 的糖果棒与鲍勃的大小为 yyy 的糖果棒交换,则有如下等式:
sumA−x+y=sumB+x−y\textit{sumA} - x + y = \textit{sumB} + x - y sumA−x+y=sumB+x−y
化简,得:
x=y+sumA−sumB2x = y + \frac{\textit{sumA} - \textit{sumB}}{2} x=y+2sumA−sumB
即对于 bobSizes\textit{bobSizes}bobSizes 中的任意一个数 y′y'y′,只要 aliceSizes\textit{aliceSizes}aliceSizes 中存在一个数 x′x'x′,满足 x′=y′+sumA−sumB2x' = y' + \dfrac{\textit{sumA} - \textit{sumB}}{2}x′=y′+2sumA−sumB,那么 {x′,y′}\{x',y'\}{x′,y′} 即为一组可行解。
为了快速查询 aliceSizes\textit{aliceSizes}aliceSizes 中是否存在某个数,我们可以先将 aliceSizes\textit{aliceSizes}aliceSizes 中的数字存入哈希表中。然后遍历 bobSizes\textit{bobSizes}bobSizes 序列中的数 y′y'y′,在哈希表中查询是否有对应的 x′x'x′。
class Solution {
public int[] fairCandySwap(int[] aliceSizes, int[] bobSizes) {
int sumA = Arrays.stream(aliceSizes).sum();
int sumB = Arrays.stream(bobSizes).sum();
int delta = (sumA - sumB) / 2;
Set rec = new HashSet();
for (int num : aliceSizes) {
rec.add(num);
}
int[] ans = new int[2];
for (int y : bobSizes) {
int x = y + delta;
if (rec.contains(x)) {
ans[0] = x;
ans[1] = y;
break;
}
}
return ans;
}
}
解题思路
数学 + 双指针
sumA - sumB 差值其实就是交换需要弥补的差距
定义需要取出来的是 xA 和 xB, 那么它们差值 xA - xB = (sumA - sumB) / 2
思路就是:
按照从小到大的排序 A 和 B
双指针,去遍历 A和 B, 考虑三种情况
xA-xB == (sumA - sumB) / 2 找到答案,返回即可
xA-xB > (sumA - sumB) / 2 , 则增大 xB
xA-xB < (sumA - sumB) / 2 , 则增大 xA
class Solution {
public:
vector fairCandySwap(vector& A, vector& B) {
int sumA = accumulate(A.begin(), A.end(), 0);
int sumB = accumulate(B.begin(), B.end(), 0);
int target = (sumA - sumB) / 2;
// 默认sort就是从小打大也可以省略 less()
sort(A.begin(), A.end(), less());
sort(B.begin(), B.end(), less());
// 双指针分别指向A和B的开头
int i = 0;
int j = 0;
int nA = A.size();
int nB = B.size();
while (i < nA && j < nB)
{
int curr = A[i] - B[j];
if (curr == target)
{
return {A[i], B[j]};
}
else if (curr > target)
{
++j;
}
else
{
++i;
}
}
// 找不到则返回空
return vector();
}
};
class Solution {
public int[] fairCandySwap(int[] aliceSizes, int[] bobSizes) {
int sum1=0,sum2=0;
for (int i = 0; i