回溯 & IP复原 & 括号生成

175 阅读1分钟

前言

“这是我参与8月更文挑战的第18天,活动详情查看:8月更文挑战

  1. NC20 数字字符串转化成IP地址(中等)
  2. NC26 括号生成(中等)

数字字符串转化成IP地址

描述: 现在有一个只包含数字的字符串,将该字符串转化成IP地址的形式,返回所有可能的情况。

例如:

给出的字符串为"25525522135",

返回["255.255.22.135", "255.255.221.35"]. (顺序没有关系)

思路分析: 回溯

  1. 已经做出的选择(记录在 temp 中)
  2. 结束条件((字符串遍历结束 && temp 集合的大小为4) || 字符串遍历结束 || temp 集合的大小大于4)
  3. 可以做出的选择(ip 地址的每一段都是 大于 0 小于等于 255 ,所以从 index 向后尝试截取 长度为 1到3 的字符串判断)

有效 IP 地址 正好由四个整数(每个整数位于 0 到 255 之间组成,且不能含有前导 0)

AC 代码:


List<List<String>> res = new ArrayList<>();

public ArrayList<String> restoreIpAddresses(String s) {

    ArrayList<String> ans = new ArrayList<>();
    dfs(s, 0, new ArrayList<>());

    for (List<String> strings : res) {

        StringBuilder sb = new StringBuilder();
        for (String i : strings) {
            sb.append(i).append(".");
        }
        ans.add(sb.substring(0, sb.length() - 1));
    }
    return ans;
}

void dfs(String s, int index, List<String> temp) {
    
    // 结束条件
    if (index == s.length() && temp.size() == 4) {
        res.add(new ArrayList<>(temp));
        return;
    }
    if (index == s.length() || temp.size() > 4) {
        return;
    }

    for (int i = 1; i <= 3 && index + i <= s.length(); i++) {
        String val = s.substring(index, index + i);
        if (check(val)) {
            temp.add(val);
            dfs(s, index + i, temp);
            temp.remove(temp.size() - 1);
        }
    }
}
// 有效 ip 段 判断
boolean check(String s) {
    if (s.length() > 1 && s.charAt(0) == '0') {
        return false;
    }
    int data = Integer.parseInt(s);
    return data >= 0 && data <= 255;
}

括号生成

描述: 给出n对括号,请编写一个函数来生成所有的由n对括号组成的合法组合。

例如,给出n=3,解集为:

"((()))", "(()())", "(())()", "()()()", "()(())",

思路分析: 回溯

  1. 已经做出的选择(记录在 temp 中)
  2. 结束条件((需要的左括号为0 && 需要的右括号为0) || (不合法的组合: 已经做出的选择中 右括号数量大于左括号的数量 ....))
  3. 可以做出的选择(选择左括号 || 选择右括号)

AC 代码:

    List<List<String>> res = new ArrayList<>();
    
    public ArrayList<String> generateParenthesis(int n) {
        // write code here
        dfs(n, n, new ArrayList<>());
        ArrayList<String> ans = new ArrayList<>();
        for (List<String> strings : res) {
            StringBuilder stringBuilder = new StringBuilder();
            for (String s : strings) {
                stringBuilder.append(s);
            }
            ans.add(stringBuilder.toString());
        }
        return ans;
    }

    void dfs(int leftCount, int rightCount, List<String> temp) {
        if (leftCount == 0 && rightCount == 0) {
            res.add(new ArrayList<>(temp));
            return;
        }

        if (leftCount < 0 || rightCount < 0 || leftCount > rightCount) {
            return;
        }

        temp.add("(");
        dfs(leftCount - 1, rightCount, temp);
        temp.remove(temp.size() - 1);

        temp.add(")");
        dfs(leftCount, rightCount - 1, temp);
        temp.remove(temp.size() - 1);

    }