165. Compare Version Numbers (Medium)
Compare two version numbers version1 and version2. If version1 > version2 return 1, if version1 < version2 return -1, otherwise return 0.
You may assume that the version strings are non-empty and contain only digits and the .
character.
The .
character does not represent a decimal point and is used to separate number sequences.
For instance, 2.5
is not "two and a half" or "half way to version three", it is the fifth second-level revision of the second first-level revision.
Here is an example of version numbers ordering:
0.1 < 1.1 < 1.2 < 13.37
Solution 1: Two Pointers, String 3ms
这道题调试了好久,一直不想上网搜别人的解法,因为感觉自己可以做出来,改来改去最后终于通过了,再上网一搜,发现果然和别人的方法不同,小有成就感。我的思路是:由于两个版本号所含的小数点个数不同,有可能是1和1.1.1比较,还有可能开头有无效0,比如01和1就是相同版本,还有可能末尾无效0,比如1.0和1也是同一版本。对于没有小数点的数字,可以默认为最后一位是小数点,而版本号比较的核心思想是相同位置的数字比较,比如题目给的例子,1.2和13.37比较,我们都知道应该显示1和13比较,13比1大,所以后面的不用再比了,再比如1.1和1.2比较,前面都是1,则比较小数点后面的数字。那么算法就是每次对应取出相同位置的小数点之前所有的字符,把他们转为数字比较,若不同则可直接得到答案,若相同,再对应往下取。如果一个数字已经没有小数点了,则默认取出为0,和另一个比较,这样也解决了末尾无效0的情况。代码如下:
class Solution {
public:
int compareVersion(string version1, string version2) {
int i = 0, j = 0, n1 = version1.size(), n2 = version2.size();
while (i < n1 || j < n2) {
string v1, v2;
while (i < n1 && version1[i] != '.') v1 += version1[i++];
int d1 = atoi(v1.c_str());
while (j < n2 && version2[j] != '.') v2 += version2[j++];
int d2 = atoi(v2.c_str());
if (d1 > d2) return 1;
if (d1 < d2) return -1;
++i, ++j;
}
return 0;
}
};
当然我们也可以不使用将字符串转为整型的atoi函数,我们可以一位一位的累加,参加如下代码:
class Solution {
public:
int compareVersion(string version1, string version2) {
int n1 = version1.size(), n2 = version2.size();
int i = 0, j = 0, d1 = 0, d2 = 0;
while (i < n1 || j < n2) {
while (i < n1 && version1[i] != '.') {
d1 = d1 * 10 + version1[i++] - '0';
}
while (j < n2 && version2[j] != '.') {
d2 = d2 * 10 + version2[j++] - '0';
}
if (d1 > d2) return 1;
else if (d1 < d2) return -1;
d1 = d2 = 0;
++i; ++j;
}
return 0;
}
};
Solution 2: StringStream 0ms
由于这道题我们需要将版本号以'.'
分开,那么我们可以借用强大的字符串流stringstream的功能来实现分段和转为整数,使用这种方法写的代码很简洁,如下所示:
class Solution {
public:
int compareVersion(string version1, string version2) {
istringstream v1(version1 + "."), v2(version2 + ".");
int d1 = 0, d2 = 0;
char dot = '.';
while (v1 || v2) {
if (v1) v1 >> d1 >> dot;
if (v2) v2 >> d2 >> dot;
if (d1 > d2) return 1;
if (d1 < d2) return -1;
d1 = d2 = 0;
}
return 0;
}
};
version 2: v1.good()
class Solution {
public:
int compareVersion(string version1, string version2) {
istringstream v1(version1 + "."), v2(version2 + ".");
int d1 = 0, d2 = 0;
char dot = '.';
while (v1.good() || v2.good()) {
if (v1.good()) v1 >> d1 >> dot;
if (v2.good()) v2 >> d2 >> dot;
if (d1 > d2) return 1;
else if (d1 < d2) return -1;
d1 = d2 = 0;
}
return 0;
}
};