LeetCode 93. Restore IP Addresses
Given a string s containing only digits, return all possible valid IP addresses that can be obtained from s. You can return them in any order.
A valid IP address consists of exactly four integers, each integer is between 0 and 255, separated by single dots and cannot have leading zeros. For example, "0.1.2.201" and "192.168.1.1" are valid IP addresses and "0.011.255.245", "192.168.1.312" and "192.168@1.1" are invalid IP addresses.
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.
实现思路:
题意是按照要求进行字符串切割,是回溯算法的一种题型,主要难在切割的细节要求上,IP段为四段,并且中间有三个'.',每一个ip段的最大值为255。
本题有剪枝的条件:
1.当初始ip段的长度大于12或者小于4的时候不可能组成合法ip段
2.当剩余ip段的段数*3大于剩余字符串长度的时候,说明肯定是没有办法组成合法的ip段的,例如"25525511135"
,当处理第一段后"2.5525511135"
,剩下三段字符长度为10位,远大于三段最大位9位的数,所以直接剪枝不需要继续递归。
同样给出一张图片便于理解回溯算法
本题的细节:
1.如果每个ip段是长度大于1的且开始位数字位0肯定是不合法的ip段
2.ip段数值要合法在0~255
才行。
AC代码:
class Solution {//本代码效率超过100%
vector<string> ans;
public:
bool judge(string str) {
if(str.length()>=2&&str[0]=='0') return false;//如果ip段是大于2位的并且以0开头则不合法
if(stoi(str)>255) return false;//ip段数值不能大于255
if(str.length()>3) return false;//用于判断最后一个ip段长不能大于3
return true;
}
void dfs(string temp,string s,int left,int cnt) {
if(cnt==0) {
string res=s.substr(left);
if(judge(res)) {
temp+=res;
ans.push_back(temp);
}
return;
}
int size=s.length();
if((size-left)>(cnt+1)*3) return;//剪枝 如果剩下的ip位数大于剩下段数*3说明肯定不合法则剪
for(int i=left; i<s.length()-1; i++) {//这里必须要让最后一个ip段最少位1位 所以i<s.length()-1
if((i-left+1)<=3) {//前三段里每一段整数不能大于3位
string res=s.substr(left,i-left+1);
if(judge(res))//是合法的ip段
dfs(temp+s.substr(left,i-left+1)+".",s,i+1,cnt-1);
}
}
}
vector<string> restoreIpAddresses(string s) {
if(s.length()>=4&&s.length()<=12) {
dfs("",s,0,3);//处理四段
}
return ans;
}
};