【回溯算法4】

力扣93.复原IP地址

链接: link

思路

判断递归回溯停止条件用分段数判断,当点数==3则表示分成了四段,最后不要忘记对第四段做一次有效性判断。

class Solution {
    List<String> res = new ArrayList<>();

    public List<String> restoreIpAddresses(String s) {
        StringBuilder sb = new StringBuilder(s);
        backTrace(sb, 0, 0);
        return res;
    }

    void backTrace(StringBuilder sb, int start, int dotcnt) {
        // 退出条件
        if (dotcnt == 3) {
            // 检查第四段是否有效
            if (isValid(sb, start, sb.length() - 1)) {
                res.add(sb.toString());
            }
            return;
        }
        for (int i = start; i < sb.length(); i++) {
            if (isValid(sb, start, i)) {
                sb.insert(i + 1, '.');// 添加点
                backTrace(sb, i + 2, dotcnt + 1);// 因为添加了.所以i+2
                sb.deleteCharAt(i + 1);
            } else {
                break;
            }
        }
    }

    boolean isValid(StringBuilder sb, int start, int end) {
        if (start > end) {
            return false;
        }
        if (sb.charAt(start) == '0' && start != end) {// x.0.x.x => 有效 x.011.x.x => 无效
            return false;
        }
        int num = 0;
        for (int i = start; i <= end; i++) {
            int digit = sb.charAt(i) - '0';
            num = num * 10 + digit;
            if (num > 255) {
                return false;
            }
        }
        return true;
    }
}

相似题型

78.子集

思路

如果把 子集问题、组合问题、分割问题都抽象为一棵树的话,那么组合问题和分割问题都是收集树的叶子节点,而子集问题是找树的所有节点!其实子集也是一种组合问题,因为它的集合是无序的,子集{1,2} 和 子集{2,1}是一样的。
那么既然是无序,取过的元素不会重复取,写回溯算法的时候,for就要从startIndex开始,而不是从0开始!
链接: link

class Solution {
    List<List<Integer>> res = new ArrayList<>();
    List<Integer> path = new ArrayList<>();
    public List<List<Integer>> subsets(int[] nums) {
        backTrace(nums,0);
        return res;
    }
    void backTrace(int[] nums,int start){
        res.add(new ArrayList<>(path));
        if(start > nums.length){
            return;
        }
        for(int i = start;i<nums.length;i++){
            path.add(nums[i]);
            backTrace(nums,i+1);
            path.remove(path.size() - 1);
        }

    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值