java寻找回文的低效解决方案
找到由两个n位数字的乘积构成的最大回文,并返回mod 1337
从n=1到n=8的输入
public class Solution {
public int largestPalindrome(int n) {
int[] arr = {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000};
int max_palindrome = 0;
for(int x = arr[n] - 1; x >= arr[n - 1]; x--){
for(int y = arr[n] -1; y >= arr[n - 1]; y--){
int maybe = x*y;
if(is_Palindrome(maybe)){
if(maybe > max_palindrome){
max_palindrome = maybe;
}
}
}
}
return max_palindrome%1337;
}
public boolean is_Palindrome(int toCheck){
char[] charArr = String.valueOf(toCheck).toCharArray();
for(int i = 0; i < charArr.length; i++){
if(charArr[i] != charArr[charArr.length - 1 - i]){
return false;
}
}
return true;
}
}
由于时间问题,此操作在n=4
失败。我能做什么
# 1 楼答案
您可以减少内环以从当前外环值开始:
这将为您提供所有可能的配对。也就是说,您需要(n*(n+1))/2次运行,而不是n^2次
在检查回文函数中,您可以使用类似的superflous函数:
从右到左检查所有字符是否与对应字符相等,但可以在中间停止。因此,您只需要现在需要的比较操作的一半
如果可能小于当前找到的最大回文数,您也可以完全跳过检查数字。现在你先检查,然后决定它是否更大
运行时性能的最后一点是,一旦到达小于当前候选回文的乘积
maybe
,就停止计算行。由于您倒数,这一行将丢失:您将无法使用较小的数字获得较高的产品您的代码也有一个缺陷。高n值的乘积大于最大整数,将产生负值。您必须将代码切换为longs
谢谢你的提问:-)
# 2 楼答案
@thst已经指出了一些很好的优化。我试过他的解决方案,但在n=5时仍然运行得很慢
如果分析显示使用字符串很慢(或者您只是不想这么做),那么您可以修改is_Palindrome()以使用整数操作。我不会展示所有代码,只展示大纲和提示:
嗯。在回答中加入一些评论:
我用C实现了@thst的解决方案。对于使用
sprintf
的字符串版本,n=7的时间大约是45秒。当用我的实现替换字符串计算时,时间始终在16秒左右-我们称之为3倍加速然后,我将计算长度的循环替换为执行表格查找的函数
这将时间缩短到了7.5秒,是“普通数学”的两倍多,是朴素字符串实现的6倍多
将
numDigits()
替换为就地版本而不是函数调用会产生一个微小但可测量的差异:在5.9s中持续运行-让我们调用它6秒记住:这是C语言,因此结果可能不适用于Java强>
总而言之,这是一个非常方便的提醒,提醒你做事情的方法不止一种,如果你经常做一些小事的话,它们可能会很重要