- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
回文数算法(C和java)
回文数算法(C和java)
问题:
将所有回文数从小到大排列,求第N个回文数。
一个正数如果顺着和反过来都是一样的(如13431,反过来也是13431),就称为回文数。约束:
回文数不能以0开头。
最小回文数是1。
思路:
许多朋友(包括我自己)一开始就思考使用循环:从1开始,判断该数是否是回文数,然后用一
个计数器记下回文数,一直到计数器得到N,返回第N个回文数。比较常用的是以下这种方法来判断是
否回文数:
static boolean isPN(int num) {
int o = num;
int tmp = 0;
//使用循环把数字顺序反转
while(num != 0) {
tmp *= 10;
tmp += num % 10;
num /= 10;
}
//如果原始数与反转后的数相等则返回true
if(tmp == o)
return true;
return false;
}
这种思路的确可得到正确结果,但随着用来测试的N的增大,效率的问题就浮现了。因为是一重
循环,效率是O(n)。所以当N非常大时,所花的时间还是十分大的。
另一种思路:
回文数的个数其实是有规律的。如:
1位回文数: 9个
2位回文数: 9个
3位回文数: 90个
4位回文数: 90个
5位回文数: 900个
6位回文数: 900个
…
我们看到9、90、900,是不是很有规律,那是什么原因?很简单,我们把回文数拆开两半
[123321]来看。两半的变化一样的,那我们只算其中一半就行了。首位不能是0,所以左半最小为
100,最大为999,共有999-100+1=900个,如此类推。
所以我们可以基于以下原则:
1、 回文数的数位每增长2,回文数的个数为原来的10倍。如从个位回文数到百位回文数,个数
从9个变为90个。
2、 个位回文数的个数是9,1、2、3、…、9。
总之理解原理后一切好办,步骤就偷懒不写了,看代码吧!
核心代码:
static long find(int index) {
int count = 0;
int number = 9; //记录数位上的回文数,如个位回文数为9
int w = 0; //记录数位
long half; //保存回文数的左半边的结果
long h = 1; //回文数的左半边的起始基数
long res; //结果
while(true) {
if(w 0 w%2 == 0) { //每进两个数位,回文数乘以10
number *= 10;
}
w++; //数位加一
if(count + number index) //回文数大于查找的回数,跳出
break;
count += number; //回文数加上当前数位上的回文数
}
index -= count; //在当前数位上的位置。如w=5,index=50,则万位上的第50个回文数是我们所求
for(int i = 0; i (w-1) / 2; i++) { //求回文数的左半边的基数,如回文数在万位上,则为100
h *= 10;
}
half = h + index; //回文数的左半边,如100 + 50 = 150
文档评论(0)