可以读通讯稿的组数

196 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第28天,点击查看活动详情

说在前面

🎈不知道大家对于算法的学习是一个怎样的心态呢?为了面试还是因为兴趣?不管是处于什么原因,算法学习需要持续保持,今天让我们一起来看看这一道题目————可以读通讯稿的组数

题目描述

校运动会上,所有参赛同学身上都贴有他的参赛号码。某班参赛同学的号码记于数组 nums 中。假定反转后的号码称为原数字的「镜像号码」。如果 两位同学 满足条件:镜像号码 A + 原号码 B = 镜像号码 B + 原号码 A,则这两位同学可以到广播站兑换一次读通讯稿的机会,为同班同学加油助威。请返回所有参赛同学可以组成的可以读通讯稿的组数,并将结果对10^9+7取余。

注意:

  • 镜像号码中如存在前置零,则忽略前置零。
  • 同一位同学可有多次兑换机会。 示例 1:
输入:nums = [17,28,39,71]

输出:3

解释:
共有三对同学,分别为 [17,28][17,39][28,39]。其中:
第一对同学:17 + 82 = 71 + 28;
第二对同学:17 + 93 = 71 + 39;
第三对同学:28 + 93 = 82 + 39

示例 2:

输入:nums = [71, 60]

输出:1

解释:
共有一对同学,为 [71, 60]。
因为 71 + 6 = 17 + 60,此处 60 的镜像号码为 6,前导零被忽略。

提示:

  • 0 <= nums.length <= 10^6
  • 0 <= nums[i] <= 10^9

思路分析

首先我们要先理解一下题意,最主要的就是这个公式:镜像号码 A + 原号码 B = 镜像号码 B + 原号码 A,我们需要在所有号码中找到所有符合这个公式的组合数。

首先数据的规模为:

  • 0 <= nums.length <= 10^6
  • 0 <= nums[i] <= 10^9

因此我们不能直接暴力进行匹配,暴力的话我们需要进行双重遍历,时间复杂度为 10^6 * 10^6 = 10 ^ 12,这样很明显会超时,所以我们需要重新想想有没有其他更加简便的方法来解决这道题。

我们假设有两个数 ab,令镜像a = a + x,镜像b = b + y,将其代入公式镜像号码 A + 原号码 B = 镜像号码 B + 原号码 A,我们可以得到:a + x + b = b + y + a,化简可以得到x = y,也就是说要想等式成立,只需要x = y即可。

所以我们可以使用一个哈希表来记录每一个原号码与镜像号码之差x的数量,后面再对每一个x进行组合即可得出答案,具体步骤如下:

  • 1、获取号码的镜像
const getReverse = function(t){
    let temp = '';
    for(let j = t.length - 1; j >= 0; j--){
        temp += t[j];
    }
    return temp
};
  • 2、统计每一个镜像与原号码之差的数量
let map = new Map();
for(let i = 0; i < nums.length; i++){
    let temp = getReverse(nums[i] + '');
    temp = temp - nums[i];
    map.set(temp,(map.get(temp) || 0) + 1);
}
  • 3、计算组合数
let res = 0;
for(let key of map.keys()){
    let ind = map.get(key);
    res += ind * (ind - 1) / 2;
    res %= 10 ** 9 + 7;
}

完整代码如下:

AC代码

/**
 * @param {number[]} nums
 * @return {number}
 */
 var numberOfPairs = function(nums) {
    let map = new Map();
    const getReverse = function(t){
        let temp = '';
        for(let j = t.length - 1; j >= 0; j--){
            temp += t[j];
        }
        return temp
    };
    for(let i = 0; i < nums.length; i++){
        let temp = getReverse(nums[i] + '');
        temp = temp - nums[i];
        map.set(temp,(map.get(temp) || 0) + 1);
    }
    let res = 0;
    for(let key of map.keys()){
        let ind = map.get(key);
        res += ind * (ind - 1) / 2;
        res %= 10 ** 9 + 7;
    }
    return res;
};

说在后面

🎉这里是JYeontu,喜欢算法,GDCPC打过卡;热爱羽毛球,大运会打过酱油。毕业一年,两年前端开发经验,目前担任H5前端开发,算法业余爱好者,有空会刷刷算法题,平时喜欢打打羽毛球🏸 ,也喜欢写些东西,既为自己记录📋,也希望可以对大家有那么一丢丢的帮助,写的不好望多多谅解🙇,写错的地方望指出,定会认真改进😊,在此谢谢大家的支持,我们下文再见🙌。