方法一:分割后比较
核心思想:可以将需要比较的两个版本号按拆分为块,逐块进行比较,根据比较结果进行返回。
注意:可能出现两个版本号块数不同,此时将较短版本号后续块中字符视为0。
图示:
核心代码:
class Solution {
public:
//用于拆分版本号的辅助函数
void helper(vector<int>& nums, string& version) {
int n = version.length(), num = 0;
for(int i = 0; i < n; ++i) {
if(version[i] == '.') {//以“.”为切分标识
nums.push_back(num);
num = 0;
} else {
num = num * 10 + (version[i] - '0');
}
}
nums.push_back(num);
}
int compare(string version1, string version2) {
vector<int> nums1, nums2; //用于存储分割后字符串(以数字形式)
helper(nums1, version1);
helper(nums2, version2);
int n1 = nums1.size(), n2 = nums2.size();
int p1 = 0, p2 = 0;
//对切分后数组进行比较
for(int i = 0; i < max(n1, n2); ++i) {
p1 = i < n1 ? nums1[i] : 0;//如果长度大于数组长度,字符视为0
p2 = i < n2 ? nums2[i] : 0;
if(p1 > p2) {
return 1;
} else if(p1 < p2) {
return -1;
}
}
return 0;
}
};复杂度分析:
时间复杂度:,其中m, n分别为两个字符串长度。需要遍历两个字符串各一次,之后对数组进行遍历
空间复杂度:,需要开辟两个数组切分后的块
方法二:双指针
核心思想:
方法一需要使用两个数组存储切分后的块,也可以采用双指针的方法,进行解析和比较,省去存储切分后的块的开销
核心代码:
class Solution {
public:
int compare(string version1, string version2) {
int len1 = 0, len2 = 0, n1 = version1.length(), n2 = version2.length();
while(len1 < n1 || len2 < n2) {
int num1 = 0, num2 = 0;//初始化为0
while(len1 < n1 && version1[len1] != '.') {
//此时如果长度较短的字符串到了尽头,不进入循环,对应数字为0
num1 = num1 * 10 + (version1[len1++] - '0');
}
while(len2 < n2 && version2[len2] != '.') {
num2 = num2 * 10 + (version2[len2++] - '0');
}
if(num1 > num2) {
return 1;
} else if(num1 < num2) {
return -1;
}
//指针后移
++len1;
++len2;
}
return 0;
}
};复杂度分析:
时间复杂度:,其中m, n分别为两个字符串长度。需要遍历到较长字符串的尽头
空间复杂度:,只用到了常数个变量



京公网安备 11010502036488号