Given a string containing only digits, restore it by returning all possible valid IP address combinations.
For example:
Given "25525511135"
,
return ["255.255.11.135", "255.255.111.35"]
. (Order does not matter)
题意是:给定一个字符串,字符串全由数字组成,在判断合法性的同时,输出所有正确的IP组合数。注意,当某个区段0开头时,那该区段只能是0
解题思路,很明显的动态规划的思想解题。就是先求出一个区段的可能的组合数,然后在第一个区段的基础上,求第二个区段的可能组合数,以此类推,因为每个区段的可能有很多,也就是剩余数字的个数很根据第一个区段的个数的变化而变化。所以注意处理这个变化,再加上细节的处理,想想还是可以做出来的。
解题第一版:使用的迭代方式求解的。虽然代码有点冗余,基本上就是这个思路。
public static List<String> restoreIpAddresses(String s) {
List<String> res=new ArrayList<String>();
if(s==null)return res;
int len=s.length();
if(len<4||len>12)return res;
int area=4;
int i=0;
while(area>0)
{
res=mergeString(s,res,len,area);//area代表目前求解的是第几个区段的IP,4代表的是第1个区段,3代表的是第2个区段
area--;
}
return res;
}
static List<String> mergeString(String s,List<String> list,int len,int area)
{
int i=1;
int listSize=list.size();
List<String> tmpList=new ArrayList<String>();
StringBuffer buffer=new StringBuffer();
char ch=' ';
int tmp=0;
if(listSize==0)//求第一个区段的IP可能组合。
{
while(i<=3&&(len-i)>=1*(area-1))
{
ch=s.charAt(i-1);
if(ch=='0'&&i==1)//当第一区段的第一位值为0的时候,该区段有且只有一种情况,那就是0
{
if((len-i)<=3*(area-1))//只有剩余的数字个数小于3*3,区段为0的数才算合法的,加入tmpList中
{
tmpList.add(String.valueOf(ch));
}
break;
}
buffer.append(ch);
tmp=Integer.valueOf(buffer.toString());
if(tmp<=255)//所求的数不能大于255
{
if((len-i)<=3*(area-1))//剩余的个数不能小于3*3
tmpList.add(buffer.toString());
}else break;
i++;
}
}else//求剩下区段的可能组合
{
for(int j=0;j<listSize;j++)//数组中前面字段的所有组合,进行单独组合求解可能数
{
i=1;
String tmpStr=list.get(j);
int strLen=tmpStr.length()-(3-area);//3-area是减去小数点的个数,就是真实字符串的长度
String str="";
while(i<=3&&(len-i-strLen)>=1*(area-1))//i代表的是每个区段的最常长度只能是3以及剩余长度应该大于(剩余区段*1)
{ //比如剩余区段是2,那最小长度应大于2,最大长度应大于2*3
buffer=buffer.delete(0,buffer.length());
buffer.append(tmpStr);
buffer.append(".");
ch=s.charAt(strLen+i-1);
if(ch=='0'&&i==1)
{
buffer.append(ch);
if((len-i-strLen)<=3*(area-1))
{
tmpList.add(buffer.toString());
}
break;
}
str+=ch;
tmp=Integer.valueOf(str);
if(tmp<=255)
{
buffer.append(str);
if((len-i-strLen)<=3*(area-1))
tmpList.add(buffer.toString());
}else
break;
i++;
}
}
}
return tmpList;
}
第二版,使用递归来解题
public ArrayList<String> restoreIpAddresses(String s) {
ArrayList<String> res = new ArrayList<String>();
if(s==null)return res;
int len=s.length();
if (len<4||len>12) return res;
String str="";
mergeString(s,str,res,0);
return res;
}
public void mergeString(String s, String str, ArrayList<String> res, int area){
if (area == 3 && isValid(s)) {
res.add(str + s);
return;
}
for(int i=1; i<=3 && i<s.length(); i++){
String substr = s.substring(0,i);
if (isValid(substr)){
mergeString(s.substring(i),str + substr + '.', res, area+1);
}
}
}
public boolean isValid(String s){
if (s.charAt(0)=='0') return s.equals("0");
int num = Integer.parseInt(s);
return num<=255 && num>0;
}
}