刷爆力扣之公平的糖果交换

简介: 刷爆力扣之公平的糖果交换

一 🏠 题目描述

888. 公平的糖果交换


爱丽丝和鲍勃拥有不同总数量的糖果。给你两个数组 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 <=1041 <= aliceSizes[i], bobSizes[j] <=105

爱丽丝和鲍勃的糖果总数量不同

题目数据保证对于给定的输入至少存在一个有效答案


二 🏠破题思路

2.1 🚀 关键信息

解决问题第一步,当然先提取题目字面上的关键信息 😎😎😎


互相交换一盒糖果,拥有相同总数量的糖果,即伪代码如下 🌺🌺🌺


sum1 = count(aliceSizes) , sum2 = count(bobSizes) //两人糖果总数量
sum1 - aliceSizes[x] + bobSizes[y] = sum2 - bobSizes[y] + aliceSizes[x] //交换后等式成立


提取完题目中的关键信息后,直接进入第二阶段,思路整理 😃😃😃



2.2 🚀 思路整理

哈希表法:把上述等式转换得 bobSizes[y] = ( sum2 - sum1 + 2 * aliceSizes[x] ) / 2 ,易知可使用哈希表法先将 bobSizes 中的数字存入哈希表, 提升查询效率(方法一) 🌷🌷🌷



双指针法:虽不及哈希表法,但还算巧妙,为开阔思维单列出


首先对 aliceSizes 和 bobSizes 进行排序,定义双指针 i ,j 和 target = (sum1 - sum2) / 2 ,双指针分别从已排序的 aliceSizes 和 bobSizes 左端开始移动 🐌🐌🐌



若 aliceSizes[i] - bobSizes[j] 小于 target ,说明 aliceSizes[i] 小了,++i
若 aliceSizes[i] - bobSizes[j] 大于 target ,说明 bobSizes[j] 小了,++j
若 aliceSizes[i] - bobSizes[j] 等于 target ,则说明等式成立,返回结果 🐳🐳🐳


整理完解题思路后,直接进入第三阶段,代码实现 😃😃😃



三 🏠 代码详解

3.1 🚀 代码实现

按照我们刚才的破题思路,直接代码走起来 👇👇👇👇


vector<int> fairCandySwap(vector<int>& aliceSizes, vector<int>& bobSizes) { //哈希表法
    int sumA = accumulate(aliceSizes.begin(), aliceSizes.end(), 0); //求和糖果总数量
    int sumB = accumulate(bobSizes.begin(), bobSizes.end(), 0); //求和糖果总数量
    int delta = (sumA - sumB) / 2; //先计算出等式成立的定值
    unordered_set<int> rec(aliceSizes.begin(), aliceSizes.end()); //将aliceSizes放入set
for (auto& y : bobSizes) { //遍历 bobSizes
        int x = y + delta; //求出满足等式的 aliceSizes 元素值
if (rec.count(x)) { //若存在于 aliceSizes 
            return{ x, y }; //返回结果
        }
    }
    return {}; //返回结果
}


按照我们刚才的破题思路,直接代码走起来 👇👇👇👇


vector<int> fairCandySwap(vector<int>& aliceSizes, vector<int>& bobSizes) { //双指针法
    int sum1 = accumulate(aliceSizes.cbegin(), aliceSizes.cend(), 0); //求和糖果总数量
    int sum2 = accumulate(bobSizes.cbegin(), bobSizes.cend(), 0); //求和糖果总数量
    std::sort(aliceSizes.begin(), aliceSizes.end()); //排序
    std::sort(bobSizes.begin(), bobSizes.end()); //排序
    int target = (sum1 - sum2) / 2; //计算出等式成立的定值
    int i =0, j =0; //定义双指针
    int len1 = aliceSizes.size(), len2 = bobSizes.size(); //获取数组长度
while (i != len1 && j != len2) { //均从左端开始遍历
        int curr = aliceSizes[i] - bobSizes[j]; //计算当前值与等式成立定值比较
if (curr == target) return{ aliceSizes[i], bobSizes[j] }; //返回结果
elseif (curr > target) ++j; //说明 bobSizes[j] 小了
else++i; //说明 aliceSizes[i] 小了
    }
    return{}; //返回结果
}


3.2 🚀 细节解析

看完 👀👀👀 全注释版的代码实现后,相信看官大大对整体逻辑已经是大写的 OK 了 😃😃😃


那么我们挖掘上述实现的晦涩细节 😖😖😖 进行解析,直接开干,走起来 👇👇👇👇


unordered_set<int> rec(aliceSizes.begin(), aliceSizes.end()); //将aliceSizes放入set

这里与常规哈希表法不同之处在于,该题不需要对数组各元素计数,而只关心 aliceSizes 值。与哈希表相比,它和数组间转换逻辑更简洁,且 count 方法同样好用 🌼🌼🌼



四 🏠 心路历程

为方便各位看官大大了解博主真实刷题过程,我把当时状态纯纯真实还原,记录在心路历程这一小节,不感兴趣的小伙伴可以直接跳过哈


博主在第一阶段提取 🚀 关键信息并没有问题,在第二阶段 🚀 思路整理中联想到使用哈希表法,未联想到双指针法。但对于实现哈希表法的想法层面,挨个置入哈希表感觉太呆了(未联想到使用 set 解决该问题 😭😭😭)


所以博主的这道题也是在阅读完官方解析后,解出来并加以记录的


相关文章
|
2月前
LeetCode第二十四题(两两交换链表中的节点)
这篇文章介绍了LeetCode第24题的解法,即如何通过使用三个指针(preNode, curNode, curNextNode)来两两交换链表中的节点,并提供了详细的代码实现。
25 0
LeetCode第二十四题(两两交换链表中的节点)
|
4月前
|
算法
LeetCode第24题两两交换链表中的节点
这篇文章介绍了LeetCode第24题"两两交换链表中的节点"的解题方法,通过使用虚拟节点和前驱节点技巧,实现了链表中相邻节点的交换。
LeetCode第24题两两交换链表中的节点
|
6月前
|
机器学习/深度学习 存储 算法
Python5种算法回溯+剪枝、字典序、递归交换、计数回溯、迭代法 实现全排列ll【力扣题47】
Python5种算法回溯+剪枝、字典序、递归交换、计数回溯、迭代法 实现全排列ll【力扣题47】
|
6月前
|
存储 算法 数据可视化
如何使用多种算法解决LeetCode第135题——分发糖果问题
如何使用多种算法解决LeetCode第135题——分发糖果问题
|
6月前
|
算法
力扣经典150题第十五题:分发糖果
力扣经典150题第十五题:分发糖果
40 0
|
6月前
|
存储 机器学习/深度学习 算法
python 3种算法 回溯法、字典序生成、递归交换 实现全排列【力扣46题】
python 3种算法 回溯法、字典序生成、递归交换 实现全排列【力扣46题】
|
6月前
|
存储 SQL 算法
|
6月前
|
算法 Java Go
【经典算法】LeetCode 1103 分糖果 II(Java/C/Python3实现含注释说明,Easy)
【经典算法】LeetCode 1103 分糖果 II(Java/C/Python3实现含注释说明,Easy)
93 0
|
7月前
|
人工智能
888. 公平的糖果棒交换(力扣)
888. 公平的糖果棒交换(力扣)
|
7月前
|
索引
【力扣刷题】删除链表的倒数第 N 个结点、两两交换链表中的节点、随机链表的复制
【力扣刷题】删除链表的倒数第 N 个结点、两两交换链表中的节点、随机链表的复制
37 0