118.版本号比较 | 豆包MarsCode AI刷题

65 阅读4分钟

问题描述

在某个项目中,每个版本都用版本号标记,由一个或多个修订号组成,修订号之间由点号 . 分隔。每个修订号可能有多位数字,并且可能会包含前导零。你需要根据两个版本号 version1 和 version2,判断哪个版本更新,或者它们是否相同。

例如,2.5.33 和 0.1 都是有效的版本号。

当比较两个版本时,从左到右依次比较它们的修订号。忽略每个修订号的前导零,直接比较修订号对应的整数值。如果其中一个版本没有足够的修订号,缺失部分默认补为 0

你需要根据以下规则返回比较结果:

  • 如果 version1 > version2,返回 1
  • 如果 version1 < version2,返回 -1
  • 如果两个版本相等,返回 0

测试样例

样例 1

输入version1 = "0.1", version2 = "1.1"
输出-1

样例 2

输入version1 = "1.0.1", version2 = "1"
输出1

样例 3

输入version1 = "7.5.2.4", version2 = "7.5.3"
输出-1

样例 4

输入version1 = "1.0", version2 = "1.0.0"
输出0

解题思路分析

可以将两个版本号按点号(.)分隔,逐个比较各个修订号。具体步骤如下:

  1. 先将两个版本号分别用 split('.') 方法分割成修订号列表。
  2. 比较两个列表的长度,确保长度一致。在较短的列表末尾补 0
  3. 按照顺序逐个比较修订号,将字符串转换为整数后进行比较。
  4. 若发现某个位置的修订号不同,直接返回 1-1
  5. 若所有修订号相同,返回 0

关键问题分析

这道题大概有以下几个关键问题:

1. 修订号长度不一致时如何处理?

比如 1.01.0.0 实际是等价的,需要在短的列表末尾补零。可以通过计算两个版本号列表的最大长度,使用列表扩展补全较短的那个版本号。

2. 如何比较修订号?

修订号需要按数值进行比较,而不是按字符串的字典序比较。例如,"001""1" 是相等的,比较时应转化为整数。

3. 优化比较逻辑

一旦某个修订号不相等,结果就可以立即返回,减少不必要的后续比较。

代码实现

def solution(version1, version2):
    # 将版本号按点号分割成修订号列表
    v1_parts = version1.split('.')
    v2_parts = version2.split('.')
    
    # 获取较长的长度
    max_len = max(len(v1_parts), len(v2_parts))
    
    # 补齐较短的版本号为相同长度
    v1_parts += ['0'] * (max_len - len(v1_parts))
    v2_parts += ['0'] * (max_len - len(v2_parts))
    
    # 逐个比较修订号
    for i in range(max_len):
        # 转换为整数进行比较
        v1_num = int(v1_parts[i])
        v2_num = int(v2_parts[i])
        
        if v1_num > v2_num:
            return 1
        elif v1_num < v2_num:
            return -1
    
    # 如果所有修订号相等
    return 0

知识点总结

这道题大概包含以下几个知识点:

1. 字符串处理

使用 split 方法分割字符串、通过字符串列表扩展补零(+= ['0'])来简化对齐操作。

2. 列表操作

列表的长度不一致时,需要补零操作,涉及到列表扩展。

3. 提前返回

在遍历过程中,只要某个修订号的大小关系明确,就可以立即返回结果,而不需要继续比较。通过提前结束的逻辑提升效率。

思考与优化

1. 时间复杂度分析

这段代码的时间复杂度为 O(n)O(n),其中 nn 是版本号中修订号的个数。因为只遍历了所有修订号一次。该复杂度可以接受。

2. 对边界条件的处理

比如:

  • 当版本号有很多前导零时,是否能够正确忽略?
  • 当两个版本号的修订号个数相差很多时,是否能正确补零?
  • 空字符串或者不符合格式的输入是否需要处理?

这段代码假设输入总是合法的。如果需要考虑非法输入,可以在开头增加输入验证,比如检查是否只有数字和点号。

3. 通用性扩展

更复杂的版本号比较,比如含字母的修订号(如 1.0.0-alpha),那么可以增加对字母部分的特殊规则处理。