CodeWars车辆里程数问题求解遇阻,寻求技术帮助
CodeWars《Catching Car Mileage Numbers》问题排查与修复
问题背景
我正在解决CodeWars上的《Catching Car Mileage Numbers》挑战:
编写一个函数解析输入的里程数,若该数是“有趣数”(定义见下文)则返回2;若接下来两英里内出现有趣数则返回1;否则返回0。
有趣数指满足以下任一条件的3位及以上数字:
- 首位非零,其余均为0:如100、90000
- 所有数字相同:如1111
- 数字递增连续(0接在9之后,如7890):如1234
- 数字递减连续(0接在1之后,如3210):如4321
- 数字是回文数:如1221、73837
- 数字匹配
awesomePhrases数组中的任一值
我的代码能通过第一批测试,但无法通过第二批测试。自行测试均通过,希望得到问题分析及解决方案,也欢迎对解题思路提出反馈。以下是我的代码:
public static int isInteresting(int number, int[] awesomePhrases) { for (int offSet = 0; offSet <= 2; offSet++) { int testNumber = number; testNumber += offSet; boolean isYellow = testNumber != number; int yellowOffset = 0; if (isYellow) { yellowOffset = 1; } //check three or more digit number boolean greaterThan99 = testNumber > 99; int[] numbers = Integer.toString(testNumber).chars().map(c -> c - '0').toArray(); int zeroCounter = 0; int identicalCounter = 0; int incrementingCounter = 0; int decrementingCounter = 0; int palindromeCounter = 0; boolean endsInZero = numbers[numbers.length - 1] == 0; for (int i = 0; i < numbers.length; i++) { //check digit followed by zeros if (numbers[i] == 0) { zeroCounter++; } if (i + 1 < numbers.length) { //check every digit is the same if (numbers[i] == numbers[i + 1]) identicalCounter++; //check ascending order if (numbers[i + 1] - numbers[i] == 1) incrementingCounter++; //check descending order if (numbers[i] - numbers[i + 1] == 1) decrementingCounter++; } } if (greaterThan99) { //check awesomePhrases for (int phrase : awesomePhrases) { if (phrase == testNumber) return 2 - yellowOffset; } //check palindrome int reversedIndex = numbers.length - 1; for (int i = 0; i < numbers.length; i++) { if (numbers[reversedIndex] == numbers[i]) { palindromeCounter++; } reversedIndex--; } if (zeroCounter == numbers.length - 1) return 2 - yellowOffset; if (identicalCounter == numbers.length - 1) return 2 - yellowOffset; if (incrementingCounter == numbers.length - 1) return 2 - yellowOffset; if (incrementingCounter == numbers.length - 2 && endsInZero) return 2 - yellowOffset; if (decrementingCounter == numbers.length - 1) return 2 - yellowOffset; if (decrementingCounter == numbers.length - 2 && endsInZero) return 2 - yellowOffset; if (palindromeCounter == numbers.length) return 2 - yellowOffset; } } return 0; }
问题分析
你的代码核心逻辑方向正确,但存在几个细节问题导致部分测试用例失败:
递增连续判断逻辑有漏洞
原代码仅通过incrementingCounter == numbers.length -2 && endsInZero判断9接0的情况,但未验证最后一组数字是否是9→0(比如数字120会被误判为符合条件)。回文数判断效率低下
原代码统计所有对应位置相等的次数,即使中途发现不相等的数字仍会继续循环,做了不必要的计算。代码结构耦合度高
所有判断逻辑堆在一个循环中,难以定位问题,也不利于后续维护。递减连续的特殊判断冗余
符合条件的递减序列(如3210)会被decrementingCounter == numbers.length -1直接命中,额外的特殊判断属于多余逻辑。
解决方案
重构代码,将每个判断条件拆分为独立辅助方法,优化逻辑严谨性与可读性:
public static int isInteresting(int number, int[] awesomePhrases) { // 优先检查当前数字 if (isInterestingNumber(number, awesomePhrases)) { return 2; } // 检查接下来1英里 if (isInterestingNumber(number + 1, awesomePhrases)) { return 1; } // 检查接下来2英里 if (isInterestingNumber(number + 2, awesomePhrases)) { return 1; } return 0; } // 辅助方法:判断单个数字是否为有趣数 private static boolean isInterestingNumber(int num, int[] awesomePhrases) { if (num < 100) { return false; } char[] digits = Integer.toString(num).toCharArray(); // 条件6:匹配指定短语 for (int phrase : awesomePhrases) { if (phrase == num) { return true; } } // 条件1:首位非零,其余全为0 boolean allZerosAfterFirst = true; for (int i = 1; i < digits.length; i++) { if (digits[i] != '0') { allZerosAfterFirst = false; break; } } if (allZerosAfterFirst) { return true; } // 条件2:所有数字相同 boolean allSame = true; char firstDigit = digits[0]; for (char c : digits) { if (c != firstDigit) { allSame = false; break; } } if (allSame) { return true; } // 条件3:递增连续(含9→0的循环) boolean isIncrementing = true; for (int i = 0; i < digits.length - 1; i++) { int current = digits[i] - '0'; int next = digits[i+1] - '0'; if ((current + 1) % 10 != next) { isIncrementing = false; break; } } if (isIncrementing) { return true; } // 条件4:递减连续 boolean isDecrementing = true; for (int i = 0; i < digits.length - 1; i++) { int current = digits[i] - '0'; int next = digits[i+1] - '0'; if (current - 1 != next) { isDecrementing = false; break; } } if (isDecrementing) { return true; } // 条件5:回文数(双指针法) boolean isPalindrome = true; int left = 0; int right = digits.length - 1; while (left < right) { if (digits[left] != digits[right]) { isPalindrome = false; break; } left++; right--; } return isPalindrome; }
优化说明
- 拆分逻辑为独立方法:将单个数字的判断逻辑分离,结构清晰,便于调试和维护。
- 严谨的递增连续判断:用
(current +1) %10 == next直接验证循环递增,彻底解决原逻辑的漏洞。 - 高效的回文数判断:双指针法一旦发现不相等的数字立即终止,减少不必要的计算。
- 提前返回逻辑:每个条件成立后立即返回,避免无效的后续判断。
- 冗余逻辑移除:删除了递减连续的多余特殊判断,简化代码。
内容的提问来源于stack exchange,提问作者João Lacerda Oliveira
相关产品推荐
相关产品推荐

