首页 > 项目 > 当前页面

LeetCode 165:版本号比较算法深度解析(compareVersion)

2026-06-19 NEW个对象

📌 LeetCode 165:版本号比较算法深度解析(compareVersion)

在系统开发与面试中,“版本号比较”是一个非常经典的问题。它不仅考察字符串处理能力,还涉及整数解析、边界补齐、逐段比较等基础算法思想。 本文将围绕 Java/Python 思维中的核心实现逻辑进行拆解,帮助你从“会做题”升级到“理解本质”。

🎯 一、问题本质拆解

版本号通常形如:1.0.3 / 2.1 / 3.0.0.1
它的比较规则并不是字符串字典序,而是“逐段整数比较”。

👉 核心规则如下:
  • 按 “.” 分割版本号
  • 每一段按整数比较,而不是字符串
  • 缺失的部分默认补 0
  • 从左到右逐段比较
⚠️ 注意:不能直接用字符串比较,比如 "1.10" 和 "1.2",字符串比较会误判大小关系。

🚀 二、算法核心思想

本题的核心可以抽象为三个步骤:
  1. 字符串拆分(split)
  2. 类型转换(str → int)
  3. 逐段比较(compare loop)

👉 本质是一种“多段整数数组比较问题”。

📌 三、标准实现代码解析

class Solution:
    # 定义比较版本号的方法(self 用于类实例调用)
    def compareVersion(self, version1: str, version2: str) -> int:

        # 1️⃣ 按 "." 拆分版本号并转为整数数组
        # 1️⃣ map(函数,可迭代集合),类似javamap转换
        v1 = list(map(int, version1.split(".")))
        v2 = list(map(int, version2.split(".")))

        # 2️⃣ 获取最大长度,用于对齐比较
        max_len = max(len(v1), len(v2))

        # 3️⃣ 补 0 保证长度一致
        v1.extend([0] * (max_len - len(v1)))
        v2.extend([0] * (max_len - len(v2)))

        # 4️⃣ 逐段比较
        for i in range(max_len):

            if v1[i] > v2[i]:
                return 1

            elif v1[i] < v2[i]:
                return -1

        # 5️⃣ 完全相等
        return 0
```

🔥 四、执行流程拆解(一步一步理解)

我们用例子:
version1 = 1.2.10
version2 = 1.2.3

👉 第一步拆分:
  • v1 = [1, 2, 10]
  • v2 = [1, 2, 3]
👉 第二步逐位比较:
  • 1 == 1 → 继续
  • 2 == 2 → 继续
  • 10 > 3 → 返回 1
✔ 最终结果:version1 更大

⚠️ 五、常见错误与坑点

❌ 错误1:直接字符串比较
❌ 错误2:忽略 1.0 = 1.0.0
❌ 错误3:未补 0 导致长度不一致
❌ 错误4:把版本当 float(会丢失精度)
💡 正确思路始终是:拆段 + 转整数 + 对齐 + 比较

🚀 六、复杂度分析

时间复杂度:O(n + m)
空间复杂度:O(n + m)

👉 n 和 m 分别表示版本号的段数。

✔ 性能已经足够优秀,可用于生产逻辑(如版本控制系统)。

🎯 七、面试进阶优化思路

上述解法已经很好,但在面试中,面试官可能会继续追问:

👉 能否不使用 split?
👉 能否 O(1) 空间?

于是就引出“双指针解析法”:
 class Solution:
    def compareVersion(self, version1: str, version2: str) -> int:
        i = j = 0
        n, m = len(version1), len(version2)

        while i < n or j < m:
            num1 = num2 = 0

            while i < n and version1[i] != '.':
                num1 = num1 * 10 + (ord(version1[i]) - 48)
                i += 1

            i += 1

            while j < m and version2[j] != '.':
                num2 = num2 * 10 + (ord(version2[j]) - 48)
                j += 1

            j += 1

            if num1 > num2:
                return 1
            elif num1 < num2:
                return -1

        return 0
```

💡 八、两种解法对比总结

方式 空间复杂度 可读性 面试评分
split补0法 O(n) ⭐⭐⭐
双指针解析 O(1) ⭐⭐⭐⭐⭐

🎯 九、总结提升

✔ 本题本质是“多段整数比较”
✔ split 解法适合快速实现
✔ 双指针解法适合面试加分
✔ 核心思想是“逐段解析 + 逐段比较”

💡 一句话总结:
版本号比较不是字符串问题,而是“结构化整数比较问题”。

相关文章

NEW个对象 NEW个对象
JAVA是世界上最好的语言