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 Credits:
Special thanks to @ts for adding this problem and creating all test cases.
分析: 题目不难,两个点之间的整数(不知道有没有为空的情况,空就认为0),比较它们的大小。数据似乎比较弱,可以转成int。但是我的建议就是不转换。而且最好别用substr这种东西,否则空间应该不是O(1),我的方法时间复杂度O(n)——n是字符串总长度,空间复杂度O(1)。
关键函数 : int get(string &s, int &begin)
从begin开始沿着s走,走到"."或者s的结束点为止,返回走的长度,注意begin也可能变化,这是为了跳过整数开头的0,这些0是无效的。例如"00110.xx"从开头走,end会走到那个'.',而begin会到“110”的第一个字符‘1’,返回的长度是3。如果begin超过了字符串长度,则end = begin,最后返回长度为0。
我们传入的参数是string的引用,并没有复制任何东西,所以空间复杂度O(1)。
接下来就是比较两个字符串begin1, begin2,长度为length1, length2的部分,当然我们可以转化为整数,也可以substr直接比较。我是自己循环比较的,因为没有首0,长度长的肯定大,长度相同的话,再逐个比较。 所以时间复杂度就是最差把两个串分别扫两遍的复杂度(第一遍确定每个begin,length,第二遍是比较),所以是O(n)的。
代码想写简单明了并不容易:
我的代码:
注意:在代码中,for循环的终止条件为i<version1.size()||j<version2.size(),而不是i<version1.size()&&j<version2.size(),,如果是后者,当version1为1, version2为1.1,会得到错误的答案。
class Solution {
private:
int get(string& s, int& start) {
int end;
for (; start<s.size()&&s[start]=='0'; start++);
for (end=start; end<s.size()&&s[end]!='.'; end++);
return end-start;
}
public:
int compareVersion(string version1, string version2) {
for (int i=0, j=0; i<version1.size()||j<version2.size(); i++,j++) { //注意这里是||,而不是&&
int p = get(version1, i), q = get(version2, j);
if (p>q) {
return 1;
} else if (p<q) {
return -1;
} else {
for (int k=0; k<p; k++) {
if (version1[i]>version2[j]) {
return 1;
} else if (version1[i]<version2[j]) {
return -1;
}
i++, j++;
}
}
}
return 0;
}
};