Article / 文章
LeetCode 第165题:比较版本号
给你两个版本号 version1 和 version2,请你比较它们。 版本号由一个或多个修订号组成,各修订号由一个 '.' 连接。每个修订号由 多位数字 组成,可能包含 前导零。每个版本号至少包含一个字符。修订号从左到右编号,下标从 0 开始,最左边的修订号下标为 0,下一个修订号下标为 1,以此类推。例如,2.5.33 和 0.1 都是有效的版本号。 比
题目描述
给你两个版本号 version1 和 version2,请你比较它们。
版本号由一个或多个修订号组成,各修订号由一个 ‘.’ 连接。每个修订号由 多位数字 组成,可能包含 前导零。每个版本号至少包含一个字符。修订号从左到右编号,下标从 0 开始,最左边的修订号下标为 0,下一个修订号下标为 1,以此类推。例如,2.5.33 和 0.1 都是有效的版本号。
比较版本号时,请按从左到右的顺序依次比较它们的修订号。比较修订号时,只需比较 忽略任何前导零后的整数值。也就是说,修订号 1 和修订号 001 相等。如果版本号没有指定某个下标处的修订号,则该修订号视为 0。例如,版本 1.0 小于版本 1.1,因为它们下标为 0 的修订号相同,而下标为 1 的修订号分别为 0 和 1,0 < 1。
返回规则如下:
- 如果
version1 > version2,返回1 - 如果
version1 < version2,返回-1 - 除此之外,返回
0
难度
中等
题目链接
示例
示例 1:
输入:version1 = "1.01", version2 = "1.001"
输出:0
解释:忽略前导零,"01" 和 "001" 都表示相同的整数 "1"
示例 2:
输入:version1 = "1.0", version2 = "1.0.0"
输出:0
解释:version1 没有指定下标为 2 的修订号,即视为 "0"
示例 3:
输入:version1 = "0.1", version2 = "1.1"
输出:-1
解释:version1 中下标为 0 的修订号是 "0",version2 中下标为 0 的修订号是 "1"。0 < 1,所以 version1 < version2
示例 4:
输入:version1 = "1.0.1", version2 = "1"
输出:1
示例 5:
输入:version1 = "7.5.2.4", version2 = "7.5.3"
输出:-1
提示
1 <= version1.length, version2.length <= 500version1和version2仅包含数字和'.'version1和version2都是 有效版本号version1和version2的所有修订号都可以存储在 32 位整数 中
解题思路
方法:分割字符串并比较
- 将两个版本号按照
.分割成修订号数组 - 逐个比较对应位置的修订号大小
- 如果一个版本号的修订号数量少于另一个,则将缺失的部分视为0进行比较
关键点:
- 将字符串按
.分割 - 将修订号转换为整数(处理前导零)
- 处理修订号数量不同的情况
- 根据比较结果返回相应的值
时间复杂度:O(max(m, n)),其中m和n分别是两个版本号的长度。 空间复杂度:O(m + n),需要存储分割后的修订号数组。
代码实现
C# 实现
public class Solution {
public int CompareVersion(string version1, string version2) {
string[] revisions1 = version1.Split('.');
string[] revisions2 = version2.Split('.');
int length = Math.Max(revisions1.Length, revisions2.Length);
for (int i = 0; i < length; i++) {
int rev1 = i < revisions1.Length ? int.Parse(revisions1[i]) : 0;
int rev2 = i < revisions2.Length ? int.Parse(revisions2[i]) : 0;
if (rev1 > rev2) {
return 1;
} else if (rev1 < rev2) {
return -1;
}
}
return 0;
}
}
Python 实现
class Solution:
def compareVersion(self, version1: str, version2: str) -> int:
revisions1 = version1.split('.')
revisions2 = version2.split('.')
length = max(len(revisions1), len(revisions2))
for i in range(length):
rev1 = int(revisions1[i]) if i < len(revisions1) else 0
rev2 = int(revisions2[i]) if i < len(revisions2) else 0
if rev1 > rev2:
return 1
elif rev1 < rev2:
return -1
return 0
C++ 实现
class Solution {
public:
int compareVersion(string version1, string version2) {
vector<int> revisions1 = split(version1);
vector<int> revisions2 = split(version2);
int length = max(revisions1.size(), revisions2.size());
for (int i = 0; i < length; i++) {
int rev1 = i < revisions1.size() ? revisions1[i] : 0;
int rev2 = i < revisions2.size() ? revisions2[i] : 0;
if (rev1 > rev2) {
return 1;
} else if (rev1 < rev2) {
return -1;
}
}
return 0;
}
private:
vector<int> split(const string& version) {
vector<int> result;
istringstream iss(version);
string token;
while (getline(iss, token, '.')) {
result.push_back(stoi(token));
}
return result;
}
};
性能分析
各语言实现的性能对比:
| 实现语言 | 执行用时 | 内存消耗 | 特点 |
|---|---|---|---|
| C# | 84 ms | 38.2 MB | 实现简洁,性能适中 |
| Python | 36 ms | 15.1 MB | 代码最简洁 |
| C++ | 0 ms | 6.1 MB | 性能最优 |
补充说明
代码亮点
- 使用分割字符串的方式处理版本号
- 处理了前导零和缺失修订号的情况
- 代码简洁明了,易于理解
常见错误
- 没有正确处理前导零
- 没有处理修订号数量不同的情况
- 直接比较字符串而不是数值,导致比较结果错误