题解 |【清晰图解】 #比较版本号#属于签到题(狗头)
默认你已经理解题意
解题思路如下
版本号由修订号组成,中间使用'.'分隔,越靠近字符串前边,修订号的优先级越大,啥意思呢?这个优先级说白了就是那一对数字优先比较的意思。当v1 > v2
时返回 1,当v1 < v2
时返回 -1,相等时返回 0。
比如说这样
上面这张图可以发现,v1= 1.02.3
, v2 = 1.02.2
,前两个修订号都是相等的,v1的第三个修订号大于v2的第三个修订号,所以v1 > v2
,返回 1。下面来讲解双指针的做法。
双指针来解
我们使用两个指针i
和j
分别指向两个字符串的开头,然后向后遍历,如果遇到小数点'.'时停下来,把每个小数点'.'分隔开的修订号解析成数字来进行比较,越靠近前边,修订号的优先级就越大,根据修订号大小关系,返回相应的数值即可。
有一个小细节
//把一段连续的字符串转换成数字
while(i < v1.size() && v1[i] != '.') num1 = num1*10+v1[i++]-'0';
这样做可以直接去前导0,同时把字符串转换成数字也容易比较大小。
具体过程如下
- 1、定义两个指针
i
和j
,初始化i = 0
,j = 0
。 - 2、两个指针分别遍历两个字符串,将每个小数点
'.'
分隔开的修订号解析成数字,并进行大小比较: 如果说num1 > num2
,返回1
; 如果说num1 < num2
,返回-1
; - 3、
i++
,j++
,两个指针都后移一步,进行下一轮的修订号解析比较。 - 4、如果遍历完两个字符串都没有返回相应结果,说明两个字符串相等,返回
0
。
时间复杂度好多
两个字符串各遍历一遍,因此时间复杂度为 O(n + m),n和m分别是两个字符串的长度。
//c++这样写
class Solution {
public:
int compareVersion(string v1, string v2) {
int i = 0, j = 0;
while(i < v1.size() || j < v2.size())
{
long long num1 = 0, num2 = 0; //数据加强了,这里要用long long
while(i < v1.size() && v1[i] != '.') num1 = num1 * 10 + v1[i++] - '0';
while(j < v2.size() && v2[j] != '.') num2 = num2 * 10 + v2[j++] - '0';
if(num1 > num2) return 1;
else if( num1 < num2) return -1;
i++,j++;
}
return 0;
}
};
我是分割线哈
//Java这样写
class Solution {
public int compareVersion(String v1, String v2) {
int i = 0, j = 0;
int n = v1.length(), m = v2.length();
while(i < n || j < m)
{
int num1 = 0, num2 = 0;
while(i < n && v1.charAt(i) != '.') num1 = num1 * 10 + v1.charAt(i++) - '0';
while(j < m && v2.charAt(j) != '.') num2 = num2 * 10 + v2.charAt(j++) - '0';
if(num1 > num2) return 1;
else if( num1 < num2) return -1;
i++; j++;
}
return 0;
}
}