93. Restore IP Addresses
问题:
给定一串由数字构成的字符串。
给任意两个数字间添加'.',一共加3次,求能得到的所有有效的IP格式。
Example 1: Input: s = "25525511135" Output: ["255.255.11.135","255.255.111.35"] Example 2: Input: s = "0000" Output: ["0.0.0.0"] Example 3: Input: s = "1111" Output: ["1.1.1.1"] Example 4: Input: s = "010010" Output: ["0.10.0.10","0.100.1.0"] Example 5: Input: s = "101023" Output: ["1.0.10.23","1.0.102.3","10.1.0.23","10.10.2.3","101.0.2.3"] Constraints: 0 <= s.length <= 3000 s consists of digits only.
解法:backtracking(回溯算法)
参数:
- path:到目前为止“.”添加后的情况。
- pos:给定字符串s的位置(上一个“.”结束,下一个可用字符位置)
- n:已经使用的“.”的个数
- optionlists:pos的下一个位置开始~s的结尾。(除去不合要求的数字,使用isValid进行check)
处理:
- 退出条件:if(n==3) (“.”已被用完)则标记需要return
- 若:pos~s的结尾,构成的字符串符合要求(isValid()==true)则将<path+最后的字符串>加入res中。
- for所有可选项:opt=[pos+1~size()) &&( isValid == true )
- 做选择:
- path+tmp+"."
- n+1
- pos=i
- 递归:
- backtracking(path+tmp+".", n+1,i,s)
- 撤销选择:path,n
- isValid:
- 传入IP区段字符串tmp->int,满足:[0~255] 且 int->string == tmp(排除"010"这种以0开头又不等于0的数字字符串)
代码参考:
1 class Solution { 2 public: 3 bool isValid(string s) { 4 int ipfield = atoi(s.c_str()); 5 string ip = to_string(ipfield); 6 if(ipfield >= 0 && ipfield <= 255 && ip == s) return true; 7 return false; 8 } 9 void backtrack(vector<string>& res, string path, int pos, string s, int n) { 10 if(n == 3) { 11 string tmp = s.substr(pos); 12 if(isValid(tmp)) { 13 res.push_back(path+tmp); 14 } 15 return; 16 } 17 for(int i = pos+1; i < s.size(); i++) { 18 string tmp = s.substr(pos, i-pos); 19 if(isValid(tmp)) { 20 backtrack(res, path+tmp+".", i, s, n+1); 21 } else return; 22 } 23 } 24 vector<string> restoreIpAddresses(string s) { 25 vector<string> res; 26 string path; 27 backtrack(res, path, 0, s, 0); 28 return res; 29 } 30 };