持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第21天,点击查看活动详情
说明:文章部分内容及图片出自网络,如有侵权请与我本人联系(主页有公众号:小攻城狮学前端)
作者:小只前端攻城狮、 主页:小只前端攻城狮的主页、 来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
【LeetCode 16.21. 交换和 】- JavaScript(双指针+reduce)
题目描述
给定两个整数数组,请交换一对数值(每个数组中取一个数值),使得两个数组所有元素的和相等。
返回一个数组,第一个元素是第一个数组中要交换的元素,第二个元素是第二个数组中要交换的元素。若有多个答案,返回任意一个均可。若无满足条件的数值,返回空数组。
示例 1:
输入: array1 = [4, 1, 2, 1, 1, 2], array2 = [3, 6, 3, 3] 输出: [1, 3]
示例 2:
输入: array1 = [1, 2, 3], array2 = [4, 5, 6] 输出: []
双指针
思路分析:
双指针思路:从已知数据中先求两个数组的和sum1,sum2,如果sum1 == sum2 返回空,再求sumAll, sumAll = sum1+sum2。如果sumAll 不是偶数返回空diff = sumAll - sum1。最后再对两个数组分别排序,用双指针的方法。如果遍历到array[j]-array[i] == diff,则返回结果。本题利用双指针解法的优势:①双方交换各自最小的值,如果交换一次后,array1的和比array2的和小,则说明array1这次交换亏了,因此array2必须拿出更大的来交换。②这样不停交换,谁亏了,对方就需要拿更大的来交换。
var findSwapValues = function(array1, array2) {
let sum1 = array1.reduce((total,cur)=>{
return total+cur
},0);
let sum2 = array2.reduce((total,cur)=>{
return total+cur
},0);
let gab = sum1 - sum2;
if(gab%2) return [];
gab/=-2;
array1.sort((a,b)=>a-b);
array2.sort((a,b)=>a-b);
let index1 = 0;
let index2 = 0;
while(index1<array1.length&&index2<array2.length){
if(array2[index2]-array1[index1]>gab){
index1++;
}else if(array2[index2]-array1[index1]<gab){
index2++;
}else {
return [array1[index1],array2[index2]];
}
}
return [];
};
reduce+Set
思路分析:使用循环把sum1值减去set1的每一个元素并且加上set2中的每一个元素的值,与sum2值减去set2的每一个元素并且加上set1中的每一个元素的值如果相同说明交换这两个值,可能是多个。于是先把两个数组的总和算出来, 然后遍历两个数组通过比较各自的总和减去两数之差是否相等来确定可替换的数值,一旦找到就返回。
var findSwapValues = function(array1, array2) {
let sum1 = array1.reduce((cb, curr) => cb + curr);
let sum2 = array2.reduce((cb, curr) => cb + curr);
array1 = [...new Set(array1)];
array2 = [...new Set(array2)];
for (let i =0; i < array1.length; i++) {
let change1 = array1[i];
for (let j = 0; j < array2.length; j++) {
let change2 = array2[j];
if (sum1 - change1 + change2 === sum2 - change2 + change1) {
return [array1[i], array2[j]];
}
}
}
return [];
};
感谢阅读,希望能对你有所帮助,文章若有错误或者侵权,可以在评论区留言或在我的主页添加公众号联系我。
写作不易,如果觉得不错,可以「点赞」+「评论」 谢谢支持❤