在当今的软件开发项目中,版本号的管理和比较至关重要。今天我将带来一道简单的“版本号比较”问题,这个问题要求我们依据特定规则对两个版本号进行比较,以确定它们的先后顺序或是否相等。
以下是具体问题描述:每个版本都用版本号标记,由一个或多个修订号组成,修订号之间由点号.分隔。每个修订号可能有多位数字,并且可能会包含前导零。你需要根据两个版本号 version1 和 version2,判断哪个版本更新,或者它们是否相同。例如,2.5.33 和 0.1 都是有效的版本号。
当比较两个版本时,从左到右依次比较它们的修订号。忽略每个修订号的前导零,直接比较修订号对应的整数值。如果其中一个版本没有足够的修订号,缺失部分默认补为0。
你需要根据以下规则返回比较结果:
- 如果
version1 > version2,返回1。 - 如果
version1 < version2,返回-1。 - 如果两个版本相等,返回
0。
首先我们来探讨解题思路。由于版本号由修订号通过点号分隔组成,且修订号可能有多位数字并包含前导零,我们的首要步骤是将版本号按照点号进行拆分,得到各个修订号的字符串数组。然后,从左到右依次比较这两个数组中的修订号。在比较过程中,需要将修订号字符串转换为整数进行比较。如果某个版本号的修订号数组较短,即没有足够的修订号,那么对于缺失的部分我们默认其值为 0。只要在比较过程中发现某个位置的修订号大小不同,就可以立即确定版本号的大小关系并返回结果;如果遍历完所有对应的修订号都未发现差异,则说明两个版本号相等。
下面详细解析代码:
public class Main {
public static void main(String[] args) {
System.out.println(solution("0.1", "1.1") == -1);
System.out.println(solution("1.0.1", "1") == 1);
System.out.println(solution("7.5.2.4", "7.5.3") == -1);
System.out.println(solution("1.0", "1.0.0") == 0);
}
public static int solution(String version1, String version2) {
// 将版本号 version1 按照点号拆分并存入字符串数组 v1
String[] v1 = version1.split("\.");
// 将版本号 version2 按照点号拆分并存入字符串数组 v2
String[] v2 = version2.split("\.");
// 循环比较两个数组中的修订号,只要有一个数组还有未比较的修订号就继续循环
for (int i = 0; i < v1.length || i < v2.length; ++i) {
int x = 0, y = 0;
// 如果 i 小于 v1 数组长度,说明 v1 还有修订号未比较,将其转换为整数
if (i < v1.length) {
x = Integer.parseInt(v1[i]);
}
// 如果 i 小于 v2 数组长度,说明 v2 还有修订号未比较,将其转换为整数
if (i < v2.length) {
y = Integer.parseInt(v2[i]);
}
// 如果 x 大于 y,说明 version1 更大,返回 1
if (x > y) {
return 1;
}
// 如果 x 小于 y,说明 version2 更大,返回 -1
if (x < y) {
return -1;
}
}
// 如果循环结束都未发现差异,说明两个版本号相等,返回 0
return 0;
}
}
在solution方法中,首先使用split方法将输入的版本号字符串version1和version2分别拆分成字符串数组v1和v2。这里使用\.作为分隔符,是因为在正则表达式中,点号是特殊字符,需要进行转义。然后进入循环,循环条件是只要v1或者v2还有未比较的修订号就继续。在循环内部,先初始化x和y为 0,用于存储当前要比较的修订号对应的整数值。如果i在v1数组的有效范围内,就将v1[i]转换为整数赋值给x;同理,如果i在v2数组的有效范围内,就将v2[i]转换为整数赋值给y。接着比较x和y,如果x大于y,直接返回 1,表示version1更大;如果x小于y,返回 -1,表示version2更大。如果循环结束都没有返回,说明所有修订号都相等,最终返回 0。
例如,对于输入version1 = "0.1", version2 = "1.1",首先拆分得到v1 = ["0", "1"],v2 = ["1", "1"]。在第一次循环中,i = 0,x = 0(因为v1[0]为 "0"),y = 1(因为v2[0]为 "1"),由于x < y,所以直接返回 -1,表示version2更大。
最后,我们来分析一下时间复杂度和空间复杂度。从时间复杂度来看,主要的操作集中在循环比较修订号上。循环的次数取决于较长的版本号修订号数组的长度,假设较长的版本号有n个修订号,那么时间复杂度为O(n)。在空间复杂度方面,主要消耗在存储拆分后的修订号字符串数组v1和v2上,其空间复杂度也与版本号的修订号数量相关,大约为O(n)。这种算法通过简单而有效的方式实现了版本号的比较,能够准确地判断两个版本号的大小关系,在软件版本管理、依赖关系处理等诸多与版本号相关的场景中具有重要的应用价值。