解析与图解
问题描述
在软件版本控制中,版本号通常由一个或多个修订号组成,修订号之间用点号 . 分隔。例如,2.5.33 和 0.1 都是有效的版本号。每个修订号可能包含多位数字,并且可能包含前导零。
给定两个版本号 version1 和 version2,我们需要比较这两个版本号,判断哪个版本更新,或者它们是否相同。比较规则如下:
- 从左到右依次比较两个版本号的修订号。
- 忽略每个修订号的前导零,直接比较修订号对应的整数值。
- 如果其中一个版本没有足够的修订号,缺失的部分默认补为
0。
根据比较结果,返回:
- 如果
version1 > version2,返回1。 - 如果
version1 < version2,返回-1。 - 如果两个版本相等,返回
0。
示例分析
让我们通过示例来理解问题:
-
示例 1:
- 输入:
version1 = "0.1",version2 = "1.1" - 输出:
-1 - 解释: 比较第一个修订号
0和1,0 < 1,所以version1 < version2。
- 输入:
-
示例 2:
- 输入:
version1 = "1.0.1",version2 = "1" - 输出:
1 - 解释: 比较第一个修订号
1和1,相等。比较第二个修订号0和缺失的修订号(视为0),0 = 0。比较第三个修订号1和缺失的修订号(视为0),1 > 0,所以version1 > version2。
- 输入:
-
示例 3:
- 输入:
version1 = "7.5.2.4",version2 = "7.5.3" - 输出:
-1 - 解释: 比较第一个修订号
7和7,相等。比较第二个修订号5和5,相等。比较第三个修订号2和3,2 < 3,所以version1 < version2。
- 输入:
-
示例 4:
- 输入:
version1 = "1.0",version2 = "1.0.0" - 输出:
0 - 解释: 比较第一个修订号
1和1,相等。比较第二个修订号0和0,相等。version1没有第三个修订号,视为0,0 = 0,所以version1 = version2。
- 输入:
算法思路
为了比较两个版本号,我们可以按照以下步骤进行:
-
分割修订号:
- 使用
split("\\.")方法将版本号字符串按点号.分割成修订号数组。
- 使用
-
确定比较长度:
- 比较两个版本号的修订号数组长度,取较大的长度作为循环的次数。
- 这样可以确保即使一个版本号比另一个版本号短,缺失的修订号也会被视为
0。
-
逐个比较修订号:
- 对于每个修订号对:
- 如果当前修订号不存在,视为
0。 - 将修订号字符串转换为整数。
- 比较两个修订号的大小:
- 如果
revision1 > revision2,返回1。 - 如果
revision1 < revision2,返回-1。 - 如果相等,继续比较下一个修订号。
- 如果
- 如果当前修订号不存在,视为
- 对于每个修订号对:
-
返回结果:
- 如果所有修订号都相等,返回
0。
- 如果所有修订号都相等,返回
图解
假设输入为 version1 = "1.0.1", version2 = "1":
-
分割修订号:
revisions1 = ["1", "0", "1"]revisions2 = ["1"]
-
比较过程:
- 比较第一个修订号
1和1,相等。 - 比较第二个修订号
0和缺失的修订号(视为0),相等。 - 比较第三个修订号
1和缺失的修订号(视为0),1 > 0,所以version1 > version2。
- 比较第一个修订号
代码详解
public class Main {
public static void main(String[] args) {
// 测试样例
System.out.println(solution("0.1", "1.1") == -1); // 输出: true
System.out.println(solution("1.0.1", "1") == 1); // 输出: true
System.out.println(solution("7.5.2.4", "7.5.3") == -1); // 输出: true
System.out.println(solution("1.0", "1.0.0") == 0); // 输出: true
}
public static int solution(String version1, String version2) {
// 将版本号按 '.' 分割成修订号数组
String[] revisions1 = version1.split("\\.");
String[] revisions2 = version2.split("\\.");
// 找出较长的修订号数组长度
int maxLength = Math.max(revisions1.length, revisions2.length);
// 逐个比较修订号
for (int i = 0; i < maxLength; i++) {
// 如果当前下标超出了修订号数组长度,视为 0
int revision1 = i < revisions1.length ? Integer.parseInt(revisions1[i]) : 0;
int revision2 = i < revisions2.length ? Integer.parseInt(revisions2[i]) : 0;
// 比较当前修订号
if (revision1 > revision2) {
return 1;
} else if (revision1 < revision2) {
return -1;
}
}
// 如果所有修订号都相等,返回 0
return 0;
}
}
-
分割修订号:
- 使用
split("\\.")方法将版本号字符串按点号.分割成修订号数组。 - 正则表达式
\\.用于匹配字面量的点号.,因为在正则表达式中.是一个特殊字符。
- 使用
-
确定比较长度:
- 使用
Math.max(revisions1.length, revisions2.length)找出较长的修订号数组长度。
- 使用
-
逐个比较修订号:
- 使用
Integer.parseInt(revisions[i])将修订号字符串转换为整数。 - 如果当前修订号不存在,视为
0。 - 比较两个修订号的大小:
- 如果
revision1 > revision2,返回1。 - 如果
revision1 < revision2,返回-1。 - 如果相等,继续比较下一个修订
- 如果
- 使用