【我也想刷穿 LeetCode啊】479. 最大回文数乘积

67 阅读3分钟

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

现在前端很多岗位面试需要有一定的算法基础,或者说经常刷算法的会优先考虑。

因此每天刷刷LeetCode非常有必要

在这之前我也刷过一些算法题,也希望以后也坚持刷,跟某掘友一样,我也想刷穿 LeetCode

一、题目描述

给定一个整数 n ,返回 可表示为两个 n 位整数乘积的 最大回文整数 。因为答案可能非常大,所以返回它对 1337 取余 。

 

示例 1:

输入:n = 2
输出:987
解释:99 x 91 = 9009, 9009 % 1337 = 987

示例 2:


输入: n = 1
输出: 9

提示:

1 <= n <= 8

来源:力扣(LeetCode) 链接:leetcode.cn/problems/la… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

二、思路分析

核心思路:当n>1时,两个位数为n的数的乘积一定是位数为2n的数

这样的话,我们在对n=1特殊处理之后,就可以对剩余的位数为2n的数分成左右两部分处理了。

当然,题目要求我们找到最大的回文数,那么,我们需要从n位数中最大的数开始迭代,这样的话,第一个找到符合条件的回文数也就是最大的了。

接下来,我们需要做的就是在这个由两个n位数组成的回文数中,去看一下它是否存在一个n位数的因子,那么我们要怎么做呢?

这里就借助到 判断一个数是否是素数的思想。

假设我们通过划分左右部分构造出来的回文数为p,如果存在两个n位数a、b,满足ab=p,那么我们可以枚举其中较大的因子x,如果xx>=p,表明可能存在另外一个数y,使得x*y=p。那么,我们怎么知道呢?其实只要 p%x==0就可以了,也就是x是p的因子,那么我们就知道y=p/x了,也就找到结果了

三、代码实现

var largestPalindrome = function (n) {
    if (n === 1) return 9;
    // 反转字符串
    const reverse = s => {
        let l = 0, r = s.length - 1
        let arr = []
        for (let x of s) arr.push(x)
        while (l < r) {
            let tmp = arr[l]
            arr[l] = arr[r]
            arr[r] = tmp
            l++, r--
        }
        let res = ''
        for (let x of arr) res += x
        return res
    }
    let lower = 1
    // 两个位数为n(n>1)的数字的乘积一定是位数为2n的数
    // 那么,如果这个数是一个回文数,则可以分解为左右两部分
    // 两部分都是一个n位的数字
    for (let i = 1; i < n; i++) lower *= 10
    // 从大到小遍历,一旦找到符合条件的值,则一定是最大值
    for (let l = lower * 10 - 1; l > lower; l--) {
        let r = reverse(l + '');
        let p = BigInt('' + l + r)    //得到回文数
        let x = BigInt(lower * 10 - 1);
        // 验证当前回文数 9889,是否存在 2~99之间的因子
        // 那么怎么判断呢? 这里用到了判断一个数是素数的方法
        // 技巧:我们枚举因子中的较大值x(如果因子相同则随便取一个)
        // 那么,我们可以考虑一下 x*x与当前构造出来的回文数p之间的关系
        // 如果x*x > p代表什么呢? 其实,代表x可能是p的因子
        // 同理,x*x=p,代表着当然是 x是p因子了,也就满足题意了
        //又或者,x*x<p,就代表不可能存在因子了,因为我们当前枚举的是较大数
        while (x * x >= p) {
            if (p % x === 0n) return p % 1337n;
            x--;
        }
    }
};

四、总结

以上就是本道题的所有内容了,本系列会持续更,欢迎点赞、关注、收藏,另外如有其他的问题,欢迎下方留言给我,我会第一时间回复你,感谢~