题解-版本号比较|豆包MarsCode AI刷题

108 阅读4分钟

问题分析

给定两个版本号字符串 version1version2,我们需要:

  1. 将这两个版本号按 . 分割成修订号数组。
  2. 比较修订号,较大的版本号被认为更“新”。
  3. 如果两个版本号在所有修订号上相等,则认为它们相等。

思路

  1. 分割版本号:版本号是由点分隔的数字组成,例如 "1.0.1"。首先,我们可以通过 split(".") 将版本号字符串分割为一个字符串数组,每个元素表示版本号的一个部分。

  2. 比较各个修订号:由于两个版本号的修订号部分长度可能不同,我们需要确保即使某个版本号较短,我们也能进行比较。在进行比较时,缺少的修订号可以认为是 0。

  3. 返回结果:通过逐个比较修订号:

    • 如果某个修订号大于另一个版本对应修订号,则当前版本号较大,返回 1
    • 如果某个修订号小于另一个版本对应修订号,则当前版本号较小,返回 -1
    • 如果所有修订号相等,则返回 0

代码详解

java
public class Main {
    public static void main(String[] args) {
        System.out.println(solution("0.1", "1.1") == -1);       // 版本 0.1 < 1.1
        System.out.println(solution("1.0.1", "1") == 1);        // 版本 1.0.1 > 1
        System.out.println(solution("7.5.2.4", "7.5.3") == -1); // 版本 7.5.2.4 < 7.5.3
        System.out.println(solution("1.0", "1.0.0") == 0);      // 版本 1.0 == 1.0.0
    }

    public static int solution(String version1, String version2) {
        // 1. 将版本号按 '.' 分割成修订号数组
        String[] v1Parts = version1.split("\."); // version1 按 '.' 分割
        String[] v2Parts = version2.split("\."); // version2 按 '.' 分割

        // 2. 获取两个版本号修订号数组的最大长度
        int maxLength = Math.max(v1Parts.length, v2Parts.length); // 找出较长的修订号数组长度

        // 3. 遍历修订号数组,逐个比较修订号
        for (int i = 0; i < maxLength; i++) {
            // 4. 获取当前修订号,如果超出数组长度,则视为 0
            int v1Part = (i < v1Parts.length) ? Integer.parseInt(v1Parts[i]) : 0; // 当前修订号(version1),如果没有则默认为0
            int v2Part = (i < v2Parts.length) ? Integer.parseInt(v2Parts[i]) : 0; // 当前修订号(version2),如果没有则默认为0

            // 5. 比较当前修订号
            if (v1Part > v2Part) {
                return 1; // 如果 version1 的修订号大于 version2 的,返回 1
            } else if (v1Part < v2Part) {
                return -1; // 如果 version1 的修订号小于 version2 的,返回 -1
            }
            // 如果当前修订号相等,继续比较下一个修订号
        }

        // 6. 如果所有修订号都相等,返回 0
        return 0; // 如果所有修订号都相等,返回 0
    }
}

详细解析

  1. split("\.")

    • version1.split("\.") 将版本号字符串按 . 分割,返回一个数组。例如,"1.0.1" 会分割成数组 ["1", "0", "1"]
    • split("\.") 中的 \. 是转义字符,因为 . 在正则表达式中是特殊字符,表示任意单个字符,因此需要转义成 \. 来表示字面上的点字符。
  2. Math.max(v1Parts.length, v2Parts.length)

    • 计算两个版本号数组的最大长度。不同版本号的修订部分可能不等长,比如 "1.0" 和 "1.0.0",这时需要视缺少的修订号为 0
  3. 修订号比较

    • 使用 Integer.parseInt(v1Parts[i]) 和 Integer.parseInt(v2Parts[i]) 将修订号从字符串转换为整数。若某个版本号数组长度较短,则该部分取值 0,通过 (i < v1Parts.length) ? Integer.parseInt(v1Parts[i]) : 0 和 (i < v2Parts.length) ? Integer.parseInt(v2Parts[i]) : 0 来处理。
  4. return 1return -1return 0

    • 如果某个修订号在 version1 中大于对应修订号在 version2 中,返回 1version1 较大)。
    • 如果某个修订号在 version1 中小于对应修订号在 version2 中,返回 -1version2 较大)。
    • 如果遍历完所有修订号后仍然没有分出大小,则返回 0,表示两个版本相等。

图解

  1. 输入: version1 = "0.1", version2 = "1.1"

    • 分割后:

      • v1Parts = ["0", "1"]
      • v2Parts = ["1", "1"]
    • 比较修订号:

      • 第一部分 0 < 1,因此返回 -1,表示 version1 较小。
  2. 输入: version1 = "1.0.1", version2 = "1"

    • 分割后:

      • v1Parts = ["1", "0", "1"]
      • v2Parts = ["1"]
    • 比较修订号:

      • 第一部分 1 == 1
      • 第二部分 0 < 0,返回 1,表示 version1 较大。
  3. 输入: version1 = "7.5.2.4", version2 = "7.5.3"

    • 分割后:

      • v1Parts = ["7", "5", "2", "4"]
      • v2Parts = ["7", "5", "3"]
    • 比较修订号:

      • 第一部分 7 == 7
      • 第二部分 5 == 5
      • 第三部分 2 < 3,返回 -1,表示 version2 较大。
  4. 输入: version1 = "1.0", version2 = "1.0.0"

    • 分割后:

      • v1Parts = ["1", "0"]
      • v2Parts = ["1", "0", "0"]
    • 比较修订号:

      • 第一部分 1 == 1
      • 第二部分 0 == 0
      • 第三部分没有对应修订号(默认为 0),所以返回 0,表示两个版本相等。

时间和空间复杂度

  • 时间复杂度O(n), 其中 n 是版本号字符串中最长的部分数(即修订号的数量)。每次对两个修订号部分进行比较,时间复杂度为 O(n)
  • 空间复杂度O(n),用于存储分割后的版本号数组。

总结

这段代码的主要目标是通过分割和比较版本号的各个修订号部分,来实现版本号的比较。它处理了不同长度的版本号,并返回了正确的比较结果。