LeetCode 93. Restore IP Addresses 复原IP地址(Java)

题目:

Given a string containing only digits, restore it by returning all possible valid IP address combinations.

Example:
Input: “25525511135”
Output: [“255.255.11.135”, “255.255.111.35”]

解答:

这类问题基本采用回溯递归的方法

IP有效的地址范围为:1.0.0.1~255.255.255.255
IP地址总共分为四段,每一段有一位,两位或三位,因此我们可以进行分段处理,对原字符串进行分段获取,并对获取的每段判断是否有效。每一段无效的情况可以分为两种:
①每一段的范围必须在 [0, 255] 之间;
②当这段只有一位时,可以为0,但如果超过一位,为两位或三位时,首位不能为0(如01,001都是无效的)

具体思路如下:

  1. 对输入字符串进行异常处理。若输入字符串的长度小于4或大于12,则不能构成有效IP地址
  2. 通过递归对字符串进行处理。其中递归的参数包括当前获取字符串的起始标志位 start 和当前获取到的第几段标志 count
  3. 通过 String.substring() 获取当前段字符串,并进行有效性判断。若该段有效,则StringBuilder.append(),不要忘记加入“.”,并继续递归
  4. 当前递归返回后,要删除当前字符串中,最后出现“.”至字符串末尾的这段字符串,便于进行下一次递归
  5. 若字符串已遍历完成start == s.length(),且字符串共有四段 count==4,则生成有效IP地址,将该字符串加入最终数组,其中记得去掉第一段中首位增加的字符“.”

代码实现如下:

class Solution {
    //IP有效地址范围:1.0.0.1~255.255.255.255
    public List<String> restoreIpAddresses(String s) {
        List<String> res = new ArrayList<>();
        //处理一些异常输入
        if(s.length() < 4 || s.length() > 12) {
            return res;
        }
        StringBuilder str = new StringBuilder();
        Recursive(s, res, str, 0, 0);
        return res;
    }
    
    private void Recursive(String s, List<String> res, StringBuilder str, int start, int count) {
    	//判断若为有效IP地址
        if(start == s.length() && count == 4) {        	
            res.add(str.toString().substring(1));	//substring(1)是因为第一次str.append("." + cur)时,会导致最终的IP地址首位是".",需去除首位的"."
            return;
        }
        for(int i=start; i<s.length(); i++) {
        	//当截取的字符串超过3位数,则return
            if(i-start > 3) {
                return;
            }
            String cur = s.substring(start, i+1);
            //排除非有效IP,若为0*或者0**的情况,则为无效直接return
            if(cur.charAt(0) == '0' && cur.length() > 1) {
                return;
            }
            //若为有效IP的一段
            if(Integer.parseInt(cur) <= 255) {
                str.append("." + cur);
                Recursive(s, res, str, i+1, count+1);
                str.delete(str.lastIndexOf("."), str.length());
            }
        }
    }
}

补充

上述解法中运用到了很多String类和StringBuilder类的API,这里再回顾整理一下:

String substring(int index):字符串的截取,截取从参数位置一直到字符串末尾,返回新的字符串
String substring(int begin, int end):截取从 begin 开始,一直到 end 结束中间的字符串。[begin, end),包含 begin,不包含 end
Strint lastIndexOf(String str):返回指定字符串在字符串中最后出现的索引位置,没有则返回-1

string str = "abcdefg";
str = str.substring(0, str.LastIndexOf("c"));
System.out.println(str);	//Output:ab

StringBuilder delete(int a,int b):删除索引从 a 到 b 的所有字符,包括a但不包括b
StringBuilder deleteCharAt(int s):删除索引 a 处的字符。

还有 Number 类中:
static int parseInt(String s):将字符串类型转换为数值类型,返回值为十进制表示的整数
static int parseInt(String s, int radix):使用 radix 指定的基数,将字符串参数解析为有符号的整数,基数可以是 10, 2, 8, 或 16 等进制数

public class Test{
    public static void main(String args[]){
        int x =Integer.parseInt("9");
        double c = Double.parseDouble("5");
        int b = Integer.parseInt("444",16);

        System.out.println(x);	//9
        System.out.println(c);	//5.0
        System.out.println(b);	//1092
    }
}

此外还有一种在转化字符串时常用到的方法:
Integer.valueOf(String str),返回值是一个保存了str值的Integer类

你可能感兴趣的:(LeetCode)