博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
leetcode-479-Largest Palindrome Product(找到两个乘数相乘得到的最大的回文数)
阅读量:5742 次
发布时间:2019-06-18

本文共 2518 字,大约阅读时间需要 8 分钟。

题目描述:

Find the largest palindrome made from the product of two n-digit numbers.

Since the result could be very large, you should return the largest palindrome mod 1337.

Example:

Input: 2

Output: 987

Explanation: 99 x 91 = 9009, 9009 % 1337 = 987

 

Note:

The range of n is [1,8].

 

要完成的函数:

int largestPalindrome(int n) 

 

说明:

1、给定一个数字n,我们可以形成一个n位的数字(十进制),比如n=2,那么我们可以形成99或者98或者12这些两位的数字。

要求从两个n位的数字的积中找到最大的回文数,比如n=2,那么我们可以形成99/99这两个2位的数字,然后积是9801,不是回文数,那么我们就要继续往下找,99*98=9702,也不是……一直往下找,直到99*91=9009这个回文数。

由于回文数数值比较大,所以我们返回回文数%1337的结果就好。

 

2、这道题传统解法是找到n位数字的最大可能值和最小可能值,比如n=2,那么上限就是99,下限就是10,然后在上下限之间的数字彼此相乘,逐个判断是否为回文数。

这种方法也能解出来,不过就是很慢。

你得找出所有数字相乘得到的积,然后一个个判断是否是回文数。

但找出所有数字相乘得到的积,不能像下面这样写:

bool ishuiwen(long t)    {        long result=0,t1=t;        while(t!=0)//得到反转之后的数,存储在result中        {            result=result*10+t%10;            t/=10;        }        return result==t1;    }    int largestPalindrome(int n)     {        if(n==1)             return 9;        int uplim=pow(10,n)-1,lowlim=pow(10,n-1);        long t;        for(long i=uplim;i>=lowlim;i--)//双重循环        {            for (long j=i;j>=lowlim;j--)            {                t=i*j;                if(ishuiwen(t))                    return t%1337;            }        }    }

上面这样写会出错的,因为双重循环从最开始的 i = 99,然后 j 一直减小,直到 i 和 j 相乘的结果是一个回文数,假设是99*55。但可能还有一个更大的回文数,假设是98*89这种,而98*89这个结果根本不会被计算出来,我们算到99*55就return了。

我们用双重循环的话,得计算出所有相乘的结果,然后一个个判断是否是回文数,最后返回最大的那个。

这样做太慢了。

 

我们尝试一下生成法,生成所有可能的回文数,然后逐个判断是否是上下限之间的数相乘的结果。这样能大大减少需要判断的个数,而且判断的过程就是判断能不能整除,非常快速。

代码如下:(附详解)

long buildhuiwen(int n)//建立回文数     {        long n1=n,result=0;        while(n!=0)        {            result=result*10+n%10;            n/=10;            n1*=10;        }        return n1+result;            }    int largestPalindrome(int n)     {        if(n==1)             return 9;        int uplim=pow(10,n)-1,lowlim=pow(10,n-1);//得到上限是uplim,下限是lowlim        for(int i=uplim;i>=lowlim;i--)         {            long cand=buildhuiwen(i);//建立2n位的回文数,比如i=99,那么建立的回文数是9999,比如i=98,建立的回文数9889,构造回文序列。            for (long j=uplim;j*j>=cand;j--)//判断得到的回文数是否能整除n位的数字            {                if(cand%j==0)                    return cand%1337;            }        }    }

上述代码中的外层循环,构造了一个回文序列,如果n=2,那么构造的回文序列是9999,9889,9779,9669,9559,9449……

接着在内层循环中,判断构造的每一个回文数是否能整除n位数。

这样做快了很多,减少了要判断的个数,而且判断过程也简化了,只需要判断是否整除。

细心的同学可能会发现,内层循环中的long j=uplim;j*j>=cand;j--,c++支持大数乘法了……

之前c++11没出的时候,大数乘法和加法都是要手工写代码实现的,现在不用啦。

上述代码实测366ms,beats 86.19% of cpp submissions。

转载于:https://www.cnblogs.com/chenjx85/p/9159043.html

你可能感兴趣的文章
MySql数据库2【常用命令行】
查看>>
动态规划---->货郎担问题
查看>>
添加虚拟子网
查看>>
Ubuntu 12.04 root用户登录设置
查看>>
存储过程点滴
查看>>
Maven编译跳过test的设置
查看>>
[LeetCode]22.Generate Parentheses
查看>>
计算A/B Test需要的样本量
查看>>
二叉树前序中序后序遍历的非递归方法
查看>>
mysql 行转列列转行
查看>>
《设计模式系列》---桥接模式
查看>>
[Unity3d]Shader 着色器 学习前了解知识
查看>>
Redrain duilib中事件委托存在的问题
查看>>
字符串的简单操作
查看>>
C#新功能--命名参数与可选参数
查看>>
strtok和strtok_r
查看>>
维辰超市:借助云商城成功转型新零售
查看>>
web.xml中<load-on-start>n</load-on-satrt>作用
查看>>
【算法】CRF
查看>>
windows 8 微软拼音输入法
查看>>