题目来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/restore-ip-addresses
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
给定一个只包含数字的字符串,复原它并返回所有可能的 IP 地址格式。
有效的 IP 地址正好由四个整数(每个整数位于 0 到 255 之间组成),整数之间用 '.' 分隔。
示例:
输入: "25525511135"
输出: ["255.255.11.135", "255.255.111.35"]
该题目是典型的深度优先搜索,回溯法,三叉树遍历。特别注意10.010.1.2这种情况是不合法的,因为010不能以0开头现.
具体算法可参考大佬的讲解: https://leetcode-cn.com/problems/restore-ip-addresses/solution/hui-su-suan-fa-hua-tu-fen-xi-jian-zhi-tiao-jian-by/
class Solution {
public:
vector<string> restoreIpAddresses(string s) {
vector<string> result_ip;
if (s.size() < 4 || s.size() > 12) return result_ip;
vector<int> num;
for (int i=0; i<s.size(); ++i)
{
num.push_back(int(s[i]-'0'));
}
vector<int> index_pos;
dfs(num, 0, 3, index_pos,result_ip);
return result_ip;
}
private:
// 深度优先搜索,回溯法,递归函数
// num传入的ip数组, start_index叠轨过程中剩下的数组开始的位置; cut_num:还剩余的点的个数(最大为3)
// index_pos:递归过程中,存储该分支下点的位置; result:正确的IP存储到这里,这里使用引用传递
bool dfs(const vector<int>& num, int start_index, int cut_num, vector<int> index_pos, vector<string>& result)
{
if (cut_num<0 || cut_num>3 || start_index < 0 || start_index >= num.size()) return false; // 临界返回
if ((num.size()-start_index) > (cut_num+1)*3 || (num.size()-start_index) < (cut_num+1)) return false; //如果剩余的数组长度过大,或者国小,返回
if (cut_num == 0)
{
if (ValidValue(num, start_index, num.size()-start_index) && index_pos.size() == 3) // 到这里,则该IP符合条件
{
//将数据转换成string
string str(num.size()+3, ' ');
int m = 0;
int dot_index = index_pos[m++];
int str_index = 0;
for (int i=0; i<num.size(); ++i)
{
if (i == dot_index)
{
str[str_index++] = '.';
if (m < 3)
dot_index = index_pos[m++];
}
str[str_index++] = char(num[i]) + '0';
}
result.push_back(str);
}
return true;
}
cut_num--;
int i = 1;
while (i < 4) //三叉树,只有三种情况
{
if (start_index + i >= num.size()) break; //临界返回
if (!ValidValue(num, start_index, i)) //判断该数据是否满足条件,>255 ?
{
i++;
continue;
}
vector<int> tmp_pos = index_pos;
tmp_pos.push_back(start_index+i);
dfs( num, start_index+i, cut_num, tmp_pos, result);
i++;
}
return true;
}
bool ValidValue(const vector<int>& num, int start_index, int count)
{
if (num[start_index] == 0 && count > 1) return false; //针对该种情况(10.010.1.1)的判断,正确为: 100.10.1.1
int sum = 0;
int tmp = 1;
for (int i=count; i>0; --i)
{
sum += num[start_index+i-1] * tmp;
tmp *= 10;
}
if (sum > 255 || sum < 0) return false;
return true;
}
};
运行结果: