You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

CodeWars车辆里程数问题求解遇阻,寻求技术帮助

CodeWars《Catching Car Mileage Numbers》问题排查与修复

问题背景

我正在解决CodeWars上的《Catching Car Mileage Numbers》挑战:

编写一个函数解析输入的里程数,若该数是“有趣数”(定义见下文)则返回2;若接下来两英里内出现有趣数则返回1;否则返回0。
有趣数指满足以下任一条件的3位及以上数字:

  1. 首位非零,其余均为0:如100、90000
  2. 所有数字相同:如1111
  3. 数字递增连续(0接在9之后,如7890):如1234
  4. 数字递减连续(0接在1之后,如3210):如4321
  5. 数字是回文数:如1221、73837
  6. 数字匹配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;
}

问题分析

你的代码核心逻辑方向正确,但存在几个细节问题导致部分测试用例失败:

  1. 递增连续判断逻辑有漏洞
    原代码仅通过incrementingCounter == numbers.length -2 && endsInZero判断9接0的情况,但未验证最后一组数字是否是9→0(比如数字120会被误判为符合条件)。

  2. 回文数判断效率低下
    原代码统计所有对应位置相等的次数,即使中途发现不相等的数字仍会继续循环,做了不必要的计算。

  3. 代码结构耦合度高
    所有判断逻辑堆在一个循环中,难以定位问题,也不利于后续维护。

  4. 递减连续的特殊判断冗余
    符合条件的递减序列(如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;
}

优化说明

  1. 拆分逻辑为独立方法:将单个数字的判断逻辑分离,结构清晰,便于调试和维护。
  2. 严谨的递增连续判断:用(current +1) %10 == next直接验证循环递增,彻底解决原逻辑的漏洞。
  3. 高效的回文数判断:双指针法一旦发现不相等的数字立即终止,减少不必要的计算。
  4. 提前返回逻辑:每个条件成立后立即返回,避免无效的后续判断。
  5. 冗余逻辑移除:删除了递减连续的多余特殊判断,简化代码。

内容的提问来源于stack exchange,提问作者João Lacerda Oliveira

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 06:45:34