###### tags: `LeetCode` `Medium` `DFS` `String`
# LeetCode #93 [Restore IP Addresses](https://leetcode.com/problems/restore-ip-addresses/)
### (Medium)
給定一個只包含數字的字符串,用以表示一個 IP 地址,返回所有可能從 s 獲得的 有效 IP 地址 。你可以按任何順序返回答案。
有效 IP 地址 正好由四個整數(每個整數位於 0 到 255 之間組成,且不能含有前導 0),整數之間用 '.' 分隔。
例如:"0.1.2.201" 和 "192.168.1.1" 是 有效 IP 地址,但是 "0.011.255.245"、"192.168.1.312" 和 "192.168@1.1" 是 無效 IP 地址。
---
由於IPv4地址每格為0~255, 也就是1~3位數, 因此需分別考慮每位數並呼叫遞迴。
首先, 若給定字串長度小於4(4個1)或大於12(4個3)則直接返回空集合。使用計數器統計目前已完成幾個ip字節(總共4個), 當ip字節數等於4, 且ip位置等於原自串長度+3(新增3個'.')則將該ip加到答案數組中(合法ip)。
要注意的點:
1. substr的使用:與java的substring不同, C++的參數為 目標字串.substr(起始位置, 要從起始位置開始切割多少長度), 也就是說s.substr(4,2)代表從第4個字元開始往後數兩個, 也就是s[5], s[6]這兩個字元。而java的substring則是 目標字串.substring(起始位置, 終止位置)。
2. 若切割出來的ip字節長度大於1, 則不能為0開頭, 比如說: 012、01...等是非法的ip字節。
3. 當處理到第四個字節時不需要再加'.', 所以要一個額外判斷式負責決定。
---
```
class Solution {
public:
vector<string> restoreIpAddresses(string s) {
vector<string> ans;
if(s.size()>12||s.size()<4)return {};
dfs(0, s, 0, "", ans);
return ans;
}
void dfs(int index, const string& s, int times, string tmp, vector<string>& ans){
if(times==4){
if(tmp.length()==s.length()+3)
ans.push_back(tmp);
return;
}
for(int i=1;i<=3;i++){
if(index+i>s.size())break;
string subs = s.substr(index, i);
if(subs.length()>1&&subs[0]=='0')continue;
if(stoi(subs)<=255)
dfs(index+i, s, times+1, tmp+subs+(times==3?"":"."), ans);
}
}
};
```