题解 | #比较版本号#

比较版本号

http://www.nowcoder.com/practice/2b317e02f14247a49ffdbdba315459e7

方法一:分割后比较
核心思想:可以将需要比较的两个版本号按拆分为块,逐块进行比较,根据比较结果进行返回。
注意:可能出现两个版本号块数不同,此时将较短版本号后续块中字符视为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分别为两个字符串长度。需要遍历到较长字符串的尽头
空间复杂度:,只用到了常数个变量

全部评论
方法思路很有启发性,但实现上是不是有点问题啊,如果版本号有一节长度超过int表达范围,结果会有问题啊
4 回复 分享
发布于 2021-09-08 12:13
法一要用unsigned long long
点赞 回复 分享
发布于 2022-02-28 18:33
方法二错了啊。。
点赞 回复 分享
发布于 2022-03-07 17:38
方法二会超出int范围啊,可以使用long吧
点赞 回复 分享
发布于 2022-03-10 14:14
大佬,如果转为的数字也超过了long类型会不会出现问题呢?我看version字符串长度最大1000
点赞 回复 分享
发布于 2022-03-11 10:50

相关推荐

牛客771574427号:恭喜你,华杰
点赞 评论 收藏
分享
头像
11-21 11:39
四川大学 Java
是红鸢啊:忘了还没结束,还有字节的5k 违约金
点赞 评论 收藏
分享
12 3 评论
分享
牛客网
牛客企业服务