【LeetCode】每日一题 面试题 16.21. 交换和

120 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第4天,点击查看活动详情

面试题 16.21. 交换和

给定两个整数数组,请交换一对数值(每个数组中取一个数值),使得两个数组所有元素的和相等。

返回一个数组,第一个元素是第一个数组中要交换的元素,第二个元素是第二个数组中要交换的元素。若有多个答案,返回任意一个均可。若无满足条件的数值,返回空数组。

「示例1:」
输入: array1 = [4, 1, 2, 1, 1, 2], array2 = [3, 6, 3, 3]
输出: [1, 3]
「示例2:」
输入: array1 = [1, 2, 3], array2 = [4, 5, 6]
输出: []
「提示:」
1 <= array1.length, array2.length <= 100000

解题思路

// 第一种
一般套路,先求两个数组总和sum1+sum2,得到两数组各自的目标和target,再逐个遍历数组array2,对任意一个数字num,如果把它换到array1中且array1中存在target - (sum2-num),则num和target - (sum2-num)就是结果
​
// 第二种
先判断两个数组的和是不是相等,相等的话不用做任何操作
在判断和相加是不是偶数,如果不是,不能凑成两个和相等的数组
​
剩下就是可能的情况了
​
先求的两个数组和的差值,目标值就是差值除以2的值,只要我们能从和大的数组中取出一个数,减去和小的数组中取出一个数,差值为目标值,这两个数就是结果
​
先将两个数组排序
里用双指针,分别从和大的数组、和小的数组中分别取得一个数,取两个数的差值
如果差值小于目标值,减数要增加,就移动和大的数组的指针
如果差值大于目标值,被减数就要增加,就移动和小的数组的指针
直至结束

代码实现

// 第一种
var findSwapValues = function(array1, array2) {
  let sum1 = 0, sum2 = 0
  for(const num of array1) sum1 += num
  for(const num of array2) sum2 += num
  const target = (sum1 + sum2) / 2
  if(target !== Math.floor(target)) return []
  const set = new Set(array1)
  for(let num of array2) {
    if(set.has(target - (sum2 - num))) return [target - (sum2 - num), num]
  }
  return []
};
​
// 第二种
/**
 * @param {number[]} array1
 * @param {number[]} array2
 * @return {number[]}
 */
var findSwapValues = function(array1, array2) {
    const total1 = array1.reduce((a, b) => a + b)
    const total2 = array2.reduce((a, b) => a + b)
    const total = total1 + total2
    if (total1 === total2 || total % 2) return []
​
    array1.sort((a, b) => a - b)
    array2.sort((a, b) => a - b)
​
    let minArr = array1, maxArr = array2, arr1 = true, differ = (total2 - total1) >>> 1
    if (total2 < total1) {
        minArr = array2
        maxArr = array1
        arr1 = false
        differ = (total1 - total2) >>> 1
    }
​
    const l1 = minArr.length, l2 = maxArr.length
    let l = 0, r = 0
    while(l < l1 && r < l2) {
        const dif = maxArr[r] - minArr[l]
        if (dif < differ) {
            r++
        } else if (dif > differ) {
            l++
        } else {
            return arr1 ? [minArr[l], maxArr[r]] : [maxArr[r], minArr[l]]
        }
    }
    return []
};

如果你对这道题目还有疑问的话,可以在评论区进行留言;