简单题:版本号比较| 豆包MarsCode AI刷题

145 阅读5分钟

版本号比较

问题描述

在某个项目中,每个版本都用版本号标记,由一个或多个修订号组成,修订号之间由点号.分隔。每个修订号可能有多位数字,并且可能会包含前导零。你需要根据两个版本号 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

思路分析

这道题在刚看到题的时候还是会有一点懵的,之前没有刷过类似的版本号题型。但是多读一遍题也就会明白题意,然后能够将思路构建起来

在比较两个版本号时,关键在于逐个修订号进行比较。首先,我们将每个版本号通过点号(.)拆分成一个个修订号,并将这些修订号转化为整数。这样做可以去除修订号中的前导零,确保比较的准确性。

由于两个版本号的修订号数量可能不同,我们需要将较短的版本号补齐。补齐的方式是将缺失的修订号默认为 0,直到两个版本号的修订号数量一致。这样,我们就能够确保两个版本号在同一层级上进行比较,避免由于修订号数量不同而造成的错误判断。

接下来,我们逐个修订号进行比较。若某一修订号在 version1 中大于 version2 中对应的修订号,则 version1 更大,直接返回 1;反之,则返回 -1。如果所有修订号都相等,则两个版本号完全一致,返回 0

这种方法简单直观,能够正确处理各种情况,包括修订号数目不等、修订号包含前导零等问题。时间复杂度为 O(n),其中 n 是修订号列表的最大长度,空间复杂度为 O(n),适用于大多数版本号比较的场景。

代码展示

接下来我将展现这道题的代码

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
    
    # 如果所有修订号都相等,返回0
    return 0

代码详解

  1. def solution(version1, version2):

    • 定义一个名为 solution 的函数,接受两个参数 version1 和 version2,它们表示两个版本号。
  2. v1_parts = version1.split('.')v2_parts = version2.split('.')

    • 使用 split('.') 方法将两个版本号字符串按点(.)拆分成一个列表,列表中的每个元素代表一个版本号的部分(如 "1.2.3" 会变成 ["1", "2", "3"])。
  3. max_len = max(len(v1_parts), len(v2_parts))

    • 计算 v1_parts 和 v2_parts 中较长的部分的长度,目的是为了后面对列表进行补齐,使它们具有相同的长度。
  4. v1_parts += ['0'] * (max_len - len(v1_parts))v2_parts += ['0'] * (max_len - len(v2_parts))

    • 补齐修订号:如果一个版本号的部分少于另一个版本号的部分,那么就通过添加 '0' 来补齐。比如 1.2 和 1.2.31.2 会被补齐为 ['1', '2', '0']
  5. for i in range(max_len):

    • 遍历两个版本号的每一部分(修订号)。
  6. v1_num = int(v1_parts[i])v2_num = int(v2_parts[i])

    • 将当前部分的修订号从字符串转换为整数,进行数值比较(因为版本号的每个部分应该是数字)。
  7. if v1_num > v2_num:

    • 如果 v1 的当前部分大于 v2 的当前部分,返回 1,表示 version1 较大。
  8. elif v1_num < v2_num:

    • 如果 v1 的当前部分小于 v2 的当前部分,返回 -1,表示 version2 较大。
  9. return 0

    • 如果两个版本号的所有部分都相等,则返回 0,表示两个版本号相同。

接下来,我会举一个例子,以便于更好地去理解:

例如: 输入: solution("1.2", "1.2.0")

-   比较 `1.2` 和 `1.2.0`    -   第一个部分 `1 == 1`,相等。
    -   第二个部分 `2 == 2`,相等。
    -   第三个部分 `0 == 0`,相等。
    -   所有部分都相等,返回 `0`,表示两个版本号相同。

总结

这道题运用了多个基础知识点,主要包括以下几个方面:

  1. 字符串操作

    • 字符串分割(split() :将版本号字符串按点号(.)分割成多个修订号部分,方便后续的处理和比较。
    • 字符串与整数的转换:通过将每个修订号转换为整数(int()),自动去除其中的前导零,确保进行数值比较而不是按字面顺序比较。
  2. 列表操作

    • 列表的扩展(+= :使用 += 语法将缺失的修订号(补充为 0)添加到版本号列表中,保证两个版本号列表的长度一致。
    • 列表索引和遍历:通过索引遍历修订号列表,逐个比较每个修订号。
  3. 条件判断与比较

    • ifelifelse:通过逐个比较版本号中的修订号,并根据大小关系做出判断,决定返回的结果。
    • 数值比较:利用整数的大小关系判断两个修订号的先后,确保准确比较版本号的不同部分。

这些知识点结合在一起,形成了一个高效且易于理解的版本号比较算法。 是一道比较简单的题,只要理解题意,并且掌握了基础的知识,就可以轻松的写出来!!!