165比較版本號(istrigstream、雙指針、額外O(n)空間)

1、題目描述

比較兩個版本號 version1 和 version2。
如果 version1 > version2 返回 1,如果 version1 < version2 返回 -1, 除此之外返回 0。

你可以假設版本字符串非空,並且只包含數字和 . 字符。

 . 字符不代表小數點,而是用於分隔數字序列。

例如,2.5 不是“兩個半”,也不是“差一半到三”,而是第二版中的第五個小版本。

你可以假設版本號的每一級的默認修訂版號爲 0。例如,版本號 3.4 的第一級(大版本)和第二級(小版本)修訂號分別爲 3 和 4。其第三級和第四級修訂號均爲 0。

提示:

  1. 版本字符串由以點 (.) 分隔的數字字符串組成。這個數字字符串可能有前導零。
  2. 版本字符串不以點開始或結束,並且其中不會有兩個連續的點。

2、示例

輸入: version1 = "7.5.2.4", version2 = "7.5.3"
輸出: -1

3、題解

解法一:

基本思想:用istrigstream做

解法二:

基本思想:雙指針,一次遍歷,常數空間

version1上使用兩個指針,以'.'分割跟蹤每個數值的開始pos1和結束i,得到數值v1;version2上使用兩個指針,以'.'分割跟蹤每個數值的開始pos2和結束j,得到數值v2。分別比較對應v1和v2。

解法三:

基本思想:分割字符串,兩次遍歷,O(n)空間複雜度。將兩個字符串分割出數字保存到兩個數組,然後依次比較對應元素大小。

#include<iostream>
#include<sstream>
#include<algorithm>
#include<vector>
#include<string>
using namespace std;
class Solution {
public:
	int compareVersion(string version1, string version2) {
		//基本思想:用istrigstream做
		istringstream nums1(version1);
		istringstream nums2(version2);
		char c;
		int v1, v2;
		//while裏面判斷既不能用&&也不能用||,因爲用&&,nums1>>v1成功後已經輸出v1了
		while (bool(nums1 >> v1) + bool(nums2 >> v2))
		{
			if (v1 > v2)
				return 1;
			if (v1 < v2)
				return -1;
			v1 = 0;
			v2 = 0;
			nums1 >> c;
			nums2 >> c;
		}
		return 0;
	}
};
class Solution1 {
public:
	int compareVersion(string version1, string version2) {
		//基本思想:雙指針,一次遍歷,常數空間
		//version1上使用兩個指針,以'.'分割跟蹤每個數值的開始pos1和結束i,得到數值v1
		//version2上使用兩個指針,以'.'分割跟蹤每個數值的開始pos2和結束j,得到數值v2
		//分別比較對應v1和v2
		int pos1 = 0, pos2 = 0, i = 0, j = 0, v1, v2, flag1 = 0, flag2 = 0;
		while (i <= version1.size() && j <= version2.size())
		{
			if (i == version1.size() || version1[i] == '.')
				flag1 = 1;	
			else
				i++;
			if (j == version2.size() || version2[j] == '.')
				flag2 = 1;
			else
				j++;
			if (flag1 && flag2)
			{
				v1 = stoi(version1.substr(pos1, i - pos1));
				v2 = stoi(version2.substr(pos2, j - pos2));
				if (v1 > v2)
					return 1;
				if (v1 < v2)
					return -1;
				flag1 = 0;
				flag2 = 0;
				i++;
				j++;
				pos1 = i;
				pos2 = j;
			}
		}
		while (i <= version1.size())
		{
			if (version1[i] != '.' && version1[i] != '0')
				return 1;
			i++;
		}
		while (j <= version2.size())
		{
			if (version2[j] != '.' && version2[j] != '0')
				return -1;
			j++;
		}
		return 0;
	}
};
class Solution2 {
public:
	int compareVersion(string version1, string version2) {
		//基本思想:分割字符串,兩次遍歷,O(n)空間複雜度
		//將兩個字符串分割出數字保存到兩個數組,然後依次比較對應元素大小
		vector<int> v1, v2;
		int pos = 0, i;
		for (i = 0; i <= version1.size(); i++)
		{
			if (i == version1.size() || version1[i] == '.')
			{
				v1.push_back(stoi(version1.substr(pos, i - pos)));
				pos = i + 1;
			}
		}
		pos = 0;
		for (i = 0; i <= version2.size(); i++)
		{
			if (i == version2.size() || version2[i] == '.')
			{
				v2.push_back(stoi(version2.substr(pos, i - pos)));
				pos = i + 1;
			}
		}
		for (i = 0; i < v1.size() && i < v2.size(); i++)
		{
			if (v1[i] > v2[i])
				return 1;
			if (v1[i] < v2[i])
				return -1;
		}
		while (i < v1.size())
		{
			if (v1[i] != 0)
				return 1;
			i++;
		}
		while (i < v2.size())
		{
			if (v2[i] != 0)
				return -1;
			i++;
		}
		return 0;
	}
};

int main()
{
	Solution solute;
	string version1 = "7.5.2.4", version2 = "7.5";
	cout << solute.compareVersion(version1, version2) << endl;
	return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章