题解 |【清晰图解】 #比较版本号#属于签到题(狗头)

默认你已经理解题意

alt

解题思路如下

版本号由修订号组成,中间使用'.'分隔,越靠近字符串前边,修订号的优先级越大,啥意思呢?这个优先级说白了就是那一对数字优先比较的意思。当v1 > v2时返回 1,当v1 < v2时返回 -1,相等时返回 0。

比如说这样 上面这张图可以发现,v1= 1.02.3, v2 = 1.02.2,前两个修订号都是相等的,v1的第三个修订号大于v2的第三个修订号,所以v1 > v2,返回 1。下面来讲解双指针的做法。

双指针来解

我们使用两个指针ij分别指向两个字符串的开头,然后向后遍历,如果遇到小数点'.'时停下来,把每个小数点'.'分隔开的修订号解析成数字来进行比较,越靠近前边,修订号的优先级就越大,根据修订号大小关系,返回相应的数值即可。

有一个小细节

//把一段连续的字符串转换成数字
while(i < v1.size() && v1[i] != '.') num1 = num1*10+v1[i++]-'0';

这样做可以直接去前导0,同时把字符串转换成数字也容易比较大小。

具体过程如下

  • 1、定义两个指针 ij,初始化i = 0j = 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;
    }
}
全部评论

相关推荐

11-05 07:29
贵州大学 Java
点赞 评论 收藏
分享
评论
1
收藏
分享
牛客网
牛客企业服务