在Euler项目中,我在StackOverflow中遇到了许多问题4的解决方案。我的问题不是要从已经在StackOverflow中实现的项目Euler再次提出问题4的解决方案。相反,我遇到了一种改进的解决方案Improved solution by ROMANIA_engineer。 对于改进的解决方案,我有两个问题。无论如何,我已经在下面发布了该解决方案,供人们研究。
public static void main(String[] args) {
int max = -1;
for ( int i = 999 ; i >= 100 ; i--) {
if ( max >= i*999 ) {
break;
}
for (int j = 999 ; j >= i ; j-- ) {
int p = i * j;
if ( max < p && isPalindrome(p) ) {
max = p;
}
}
}
System.out.println(max > -1? max : "No palindrome found");
}
问题
- 为什么有条件(max> = i * 999)?通过包括这种便宜的操作,我们要实现什么?
在下面的代码段中,
for (int j = 999 ; j >= i ; j-- ) {
int p = i * j;
if ( max < p && isPalindrome(p) ) {
max = p;
}
}
- 被赋予
j >= 100
而不是j >= i
。我可以看到节省了大量时间,但是,我想知道其背后的意图。
答案 0 :(得分:1)
要回答问题1,检查(max >= i * 999)
的原因是您可能已经偶然发现了两个3位数字的乘积,该数字是回文但大于i * 999
。因为外部for循环从i = 999开始,所以一旦找到新的最大值,则新的最大值可能会大于下一个迭代中i值递减的最大回文乘积。例如,如果我们发现回文积为926 * 998,其中i = 926和j = 998,并将新的最大值设置为该乘积。请注意,这只是一个假设,我不知道该产品是否是回文。然后内部for循环在迭代i = 926上完成。然后在外部for循环的下一次迭代中,i现在为925,并且由于925 * 999小于926 * 998,因此无需继续查找最大回文产品,因为已经找到了。原因是,此时925 * 999是可以计算的最大回文乘积。
要回答问题2,使用j >= i
的原因是避免重复计算乘积。例如,假设条件是j >= 100
。在内部for循环的第一次迭代中,当j为999且i也为999时,我们最终可能会计算从999 * 999、999 * 998一直到999 * 100的乘积。但是,如果内部for循环曾经达到i现在为100而j为999的地步,那么最终您将重复计算100 *999。请注意,这只是一个示例,甚至可能无法达到这一点。