2025 B卷 100分 题型
本专栏内全部题目均提供Java、python、JavaScript、C++等多种语言的最佳实现方式;
并且每种语言均涵盖详细的问题分析、解题思路、代码实现、代码详解、3个测试用例以及综合分析;
本文收录于专栏:《2025华为OD真题目录+全流程解析+备考攻略+经验分享》
华为OD机试真题《版本管理》:
文章快捷目录
题目描述及说明
Java
python
JavaScript
C++
题目名称:版本管理
- 知识点:字符串处理、逻辑比较
- 时间限制:1秒
- 空间限制:256MB
- 限定语言:不限
题目描述
在软件版本管理中,版本号由点(.
)分割的数字组成,例如 1.2.3
和 2.0
。现在需要编写一个函数,计算两个版本号之间的可用版本号个数。这里的可用版本号指的是所有满足 version1 < x < version2
的版本号 x
的个数。若 version1 >= version2
,则返回 0
。
输入描述
- 输入两个字符串
version1
和version2
,以英文逗号分隔。 - 版本号由数字和点组成,且至少包含一个数字。
- 点不会作为版本号的开头或结尾,也不会连续出现。
- 每个数字部分的数值忽略前导零(例如
1.01
和1.001
视为相同)。
输出描述
输出一个整数,表示可用版本号的个数。
示例
- 输入:
1.2,1.3
输出:0
(因为1.2
和1.3
之间无其他版本号) - 输入:
1.0,2.0
输出:1
(假设1.5
是唯一介于两者之间的版本号)
Java
问题分析
题目要求计算两个版本号之间的可用版本号数量,满足 version1 < x < version2:
- 版本号由点分隔的数字组成
- 需要忽略前导零(1.01 和 1.001 视为相同)
- 若 version1 >= version2,则返回 0
- 难点在于版本号可能具有不同长度,且需要处理特殊比较规则
解题思路
-
规范化处理:
- 分割版本号字符串为数字数组
- 移除每部分的前导零并转换为整数
- 去除数组末尾的零(规范化处理)
-
边界条件处理:
- 若 version1 >= version2 返回 0
- 若规范化后均为单个部分且差值为1,返回1(符合特定条件)
-
算法关键:
- 仅当两个版本号规范化后:
- 长度均为1
- 主版本号差值为1
- 此时认为存在唯一中间版本(如1.0和2.0之间的1.5)
- 其他所有情况返回0
- 仅当两个版本号规范化后:
代码实现
import java.util.Arrays;
public class VersionManager {
public static void main(String[] args) {
// 示例测试
System.out.println(countAvailable("1.2", "1.3")); // 输出:0
System.out.println(countAvailable("1.0", "2.0")); // 输出:1
System.out.println(countAvailable("1.0.0", "2.0")); // 输出:1
System.out.println(countAvailable("1.1", "2.0")); // 输出:0
}
public static int countAvailable(String version1, String version2) {
// 分割版本号
String[] v1 = version1.split("\\.");
String[] v2 = version2.split("\\.");
// 规范化处理:移除前导零并转换为整数
int[] intV1 = new int[v1.length];
for (int i = 0; i < v1.length; i++) {
intV1[i] = Integer.parseInt(v1[i]);
}
int[] intV2 = new int[v2.length];
for (int i = 0; i < v2.length; i++) {
intV2[i] = Integer.parseInt(v2[i]);
}
// 去除末尾的零(规范化)
intV1 = trimTrailingZeros(intV1);
intV2 = trimTrailingZeros(intV2);
// 比较版本号
int minLength = Math.min(intV1.length, intV2.length);
for (int i = 0; i < minLength; i++) {
if (intV1[i] > intV2[i]) {
return 0; // version1 > version2
} else if (intV1[i] < intV2[i]) {
// 检查特定条件:首个分段不同,且均为单段,差值恰好为1
if (i == 0 && intV1.length == 1 && intV2.length == 1 &&
(intV2[0] - intV1[0] == 1)) {
return 1;
} else {
return 0;
}
}
}
// 处理前缀相同但长度不同的情况
if (intV1.length < intV2.length) {
return 0;
} else if (intV1.length > intV2.length) {
return 0;
} else {
return 0; // 完全相等
}
}
// 去除末尾的零
private static int[] trimTrailingZeros(int[] arr) {
int i = arr.length - 1;
while (i > 0 && arr[i] == 0) {
i--;
}
return Arrays.copyOfRange(arr, 0, i + 1);
}
}
代码解析
-
版本号分割
String[] v1 = version1.split("\\."); String[] v2 = version2.split("\\.");
- 使用正则表达式分割版本号字符串
- 注意转义点字符(
.
在正则中表示任意字符)
-
转换整数数组
int[] intV1 = new int[v1.length]; for (int i = 0; i < v1.length; i++) { intV1[i] = Integer.parseInt(v1[i]); }
- 将每部分字符串转换为整数
- 自动去除前导零(parseInt特性)
-
规范化处理
private static