【第 74 场力扣双周赛】6020. 将数组划分成相等数对(简单)

142 阅读1分钟

“Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情。”

一、题目描述

给你一个整数数组 nums ,它包含 2 * n 个整数。

你需要将 nums 划分成 n 个数对,满足:

  • 每个元素 只属于一个 数对。
  • 同一数对中的元素 相等 。

如果可以将 nums 划分成 n 个数对,请你返回 true ,否则返回 false 。

 

示例 1:

输入: nums = [3,2,3,2,2,2]
输出: true
解释:
nums 中总共有 6 个元素,所以它们应该被划分成 6 / 2 = 3 个数对。
nums 可以划分成 (2, 2) ,(3, 3) 和 (2, 2) ,满足所有要求。

示例 2:

输入: nums = [1,2,3,4]
输出: false
解释:
无法将 nums 划分成 4 / 2 = 2 个数对且满足所有要求。

 

提示:

  • nums.length == 2 * n
  • 1 <= n <= 500
  • 1 <= nums[i] <= 500

二、思路分析

题目要求划分的 nums.length / 2 个数对中每个元素都要相同且不重复,如果可以做到则 return true ,否则 return false
题意很简单,有多个方法可以完成,下面说说两个比较好的解法。

解法一,哈希表,思路如下:

  • 建一个空间大小为 nums.length + 1 的数组 arr ,并赋值为 0 ,用来标识 nums 中每个元素有多少个。
  • 遍历 arr 数组,如果当前元素不是 2 的倍数,说明该元素无法配对成 两个元素都相同 的数对,则 return false
  • 如果遍历到最后依然能配对成功,则说明可以满足题意, return true

解法二,排序,思路如下:

  • 从小到大排序 nums 数组。
  • 0 开始遍历 nums 数组,如果当前元素等于其后一个元素,则可以匹配成数对,这时遍历到当前元素的后两个元素,继续判断是否相等;如果不相等的话,后面也不可能会有与当前元素相等的值了(因为数组已经是升序的了),直接 return false

三、AC 代码

解法一:哈希表

var divideArray = function(nums) {
    const arr = new Array(501).fill(0);
    for (let x of nums) {
        arr[x]++;
    }
    for (let x of arr) {
        if (x % 2 !== 0) {
            return false;
        }
    }
    return true;
};

解法二:排序

var divideArray = function(nums) {
    nums.sort((a, b) => a - b);
    for (let i = 0; i < nums.length; i += 2) {
        if (nums[i] !== nums[i + 1]) {
            return false;
        }
    }
    return true;
};

四、总结

这道题本身不难,需要注意的是第一种解法,我用 js 写的时候没有给 arr 数组定大小,导致建了一个空数组,不能给元素赋值,一直为 NaN ,看到题目的提示 1 <= nums[i] <= 500 才意识到给 arr 数组定大小即可。

稍微拓展一下,js 创建数组的几种方式:

var a = Array();
var b = new Array();
var c = [];

这几种方式都能成功创建数组,在实际使用中:

  • 从性能上来讲,new Array() 在初始化大数组的时候,性能更加优异
  • 从语言特性上讲,虽然使用 new,会增加多一层的对象包裹,而使得内存冗余。但使用 new 后更加符合了 js 对象化继承的概念。自我感觉上,使用 new 应该是更加好的方式。