Restore IP Addresses---LeetCode

自己写的

class Solution {
public:
	vector<string> restoreIpAddresses(string s) {
		// 先排除一波
		vector<string> ret;
		if (s.size() > 4 * 3 || s.size() < 4) return ret;

		// 再排除一下不全是数字的 
		if (!isNum(s)) return ret;

		ret = restoreIpAddressesHelper(s, s.size(), 4);
		return ret;
	}
private:
	vector<string> restoreIpAddressesHelper(const string s, const int strlen, const int count)
	{
		vector<string> ret;
		if (count < 1 || strlen > count * 3 || strlen < count)
			return ret;
		if (count == 1)
		{
			
			int i = -1;
			// 第一位不能是0
			if (strlen > 1 && s[0] == '0') 
				return ret;
			// 如果只有3位 看是否符合要求
			if (strlen == 3)
			{
				i = convertStringToInt(string(s, 0, 3));
				if (i > 255)
				{
					return ret;
				}
			}
			string str = string(s, 0, strlen) + '.';
			ret.push_back(str);
		}
		else
		{
			bool needPoint = true;
			if (count == 4)
			{
				needPoint = false;
			}
			for (int i = 1; i <= 3 && strlen >= i; ++i)
			{
				string strCur = string(s, strlen - i, i);
				if (i != 1 && s[strlen - i] == '0')
				{
					continue;
				}
				if (i == 3)
				{
					if (convertStringToInt(strCur) > 255)
						continue;
				}
				vector<string> retTmp = restoreIpAddressesHelper(s, strlen - i, count - 1);
				for (int j = 0; j < retTmp.size(); ++j)
				{
					string strAppend = needPoint ? retTmp[j] + strCur + '.' : retTmp[j] + strCur;
					ret.push_back(strAppend);
				}
			}
		}
		return ret;
	}


	bool isNum(string s)
	{
		if (s.empty()) return false;
		for (int i = 0; i < s.size(); ++i)
		{
			if (s[i] < '0' || s[i] > '9')
				return false;
		}
		return true;
	}
	int convertStringToInt(const string &s)
	{
		int val;
		std::stringstream ss;
		ss<<s;
		ss>>val;
		return val;
	}
};

注意点:

    1. stringstream  类所在头文件 <sstream>

    2. bug:没有判断 strlen - i 是否大于等于0。导致数组越界。

     string strCur = string(s, strlen - i, i);

    3. bug:比如 12.7.0.01 这个ip的第四部分”01“不合法,应该排除掉。

leetcode上的示例:

class Solution1 {
public:
	vector<string> restoreIpAddresses(string s) {
		vector<string> res;
		vector<string> tmp;
		int count = 0;
		int n = s.length();
		solve(res, tmp, s, 0, 0, n);
		return res;
	}
	// res 存的 是每次找到的有效的最终 ip 地址,即结果
	// tmp 存的 某次查找的时候 ,每个 ip 段,最终ip 由 四段组成。
	// s	 即输入字符串一直没变
	// count 表示当前 tmp 中的 ip段 个数
	// start 表示 从s的位置索引开始找有效ip部分
	// n	 表示 s的长度 一直不变
	void solve(vector<string>& res, vector<string>& tmp, string& s, int count, int start, const int n)
	{
		if (count == 4)
		{
			if (start == n)
			{
				string t = "";
				for (int i = 0; i < 3; i++)
				{
					t += tmp[i] + ".";
				}
				t += tmp[3];
				res.push_back(t);
			}
			return;
		}
		if (start == n)
		{
			return;
		}
		for (int i = start; i < n; i++)
		{
			if (i + 1 - start > 3)
			{
				return;
			}
			string t = string(s.begin() + start, s.begin() + i + 1);
			if (t.length() > 1 && t[0] == '0')
			{
				return;
			}
			int e = stoi(t);
			if (e <= 255)
			{
				count++;
				tmp.push_back(t);
				solve(res, tmp, s, count, i + 1, n);
				count--;
				tmp.pop_back();
			}
		}
	}
};

分析:

1.从前往后找,使用tmp进行暂存,如果已经找到四个ip段了,看是否正好走完string,如果是就存入res,否则不存入。使用回溯的方法进行继续查找。

2.int e = stoi(t);  string转int的函数。 C++11中的增加的。

3.string t = string(s.begin() + start, s.begin() + i + 1); 使用迭代器进行初始化
template <class InputIterator>
  string  (InputIterator first, InputIterator last);


猜你喜欢

转载自blog.csdn.net/u012138730/article/details/80076133