day25 90. 子集 II&&78. 子集&&93.复原IP地址

  1. 子集 II
    问题描述:给定一个可能包含重复数字的数组 nums,返回其所有不重复的子集。
    代码实现:
    排序:首先对数组进行排序,以便后续处理重复元素。
    深度优先搜索(DFS):
    使用递归的方式生成所有子集。
    在递归过程中,通过 path 记录当前路径,start 表示当前搜索的起始位置。
    每次递归时,将当前路径加入结果集 res。
    遍历数组时,跳过重复的数字(if (i > start && nums[i] == nums[i - 1]) continue;)以避免重复子集。
    通过回溯(path.removeLast())尝试所有可能的子集。
    关键点:
    排序数组以处理重复元素。
    使用回溯法生成所有子集。
    跳过重复的数字以避免重复子集。

//90. 子集 II

点击查看代码
public List<List<Integer>> subsetsWithDup(int[] nums) {
        Arrays.sort(nums);
        List<List<Integer>> res = new ArrayList<>();
        LinkedList<Integer> path = new LinkedList<>();
        dfsSubsetsWithDup(nums,res,path,0);
        return res;
    }
    private void dfsSubsetsWithDup(int[] nums, List<List<Integer>> res,LinkedList<Integer> path,int start) {
        res.add(new LinkedList<>(path));
        if (start == nums.length) return;
        for (int i = start; i < nums.length; i++) {
            if(i>start&&nums[i]==nums[i-1]) continue;
            path.add(nums[i]);
            dfsSubsetsWithDup(nums, res, path, i + 1);
            path.removeLast();
        }
    }
  1. 子集
    问题描述:给定一个不含重复数字的数组 nums,返回其所有可能的子集。
    代码实现:
    深度优先搜索(DFS):
    使用递归的方式生成所有子集。
    在递归过程中,通过 path 记录当前路径,start 表示当前搜索的起始位置。
    每次递归时,将当前路径加入结果集 res。
    遍历数组时,将当前数字加入路径,递归搜索下一个数字,然后通过回溯(path.removeLast())尝试其他可能的子集。
    关键点:
    使用回溯法生成所有子集。
    不需要处理重复元素(因为输入数组不含重复数字)。
    //78. 子集
点击查看代码
public List<List<Integer>> subsets(int[] nums) {
        List<List<Integer>> res = new ArrayList<>();
        LinkedList<Integer> path = new LinkedList<>();
        dfsSubsets(nums,res,path,0);
        return res;
    }
    private void dfsSubsets(int[] nums, List<List<Integer>> res,LinkedList<Integer> path,int start) {
        res.add(new LinkedList<>(path));
        if (start == nums.length) return;
        for (int i = start; i < nums.length; i++) {
            path.add(nums[i]);
            dfsSubsets(nums, res, path, i + 1);
            path.removeLast();
        }
    }
  1. 复原 IP 地址
    问题描述:给定一个只包含数字的字符串 s,返回所有可能的复原 IP 地址。
    代码实现:
    深度优先搜索(DFS):
    使用递归的方式尝试将字符串分割成合法的 IP 地址。
    在递归过程中,通过 path 记录当前分割的数字,start 表示当前分割的起始位置。
    当分割出 4 个数字且遍历完整个字符串时,将当前路径拼接成 IP 地址并加入结果集 res。
    遍历字符串时,尝试截取长度为 1 到 3 的子串:
    如果截取的数字以 0 开头且长度大于 1,则跳过(IP 地址段不能以 0 开头)。
    如果截取的数字大于 255,则跳过(IP 地址段必须在 0 到 255 之间)。
    如果截取的数字为 0,则直接添加并递归,避免继续尝试更长的子串。
    通过回溯(path.removeLast())尝试所有可能的分割方式。
    关键点:
    使用回溯法尝试所有可能的分割方式。
    验证每个分割出的数字是否合法(是否以 0 开头、是否在 0 到 255 之间)。
    当分割出 4 个数字且遍历完整个字符串时,生成合法的 IP 地址。
点击查看代码
//93.复原IP地址
    public List<String> restoreIpAddresses(String s) {
        List<String> res = new ArrayList<>();
        LinkedList<Integer> path = new LinkedList<>();
        dfsRestoreIpAddresses(s,res,path,0);
        return res;
    }
    private void dfsRestoreIpAddresses(String s, List<String> res, LinkedList<Integer> path,int start) {
        if (start == s.length()&&path.size()==4) {
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < path.size(); i++) {
                sb.append(path.get(i));
                if (i<path.size()-1){
                    sb.append(".");
                }
            }
            res.add(sb.toString());
        }
        for (int i = 1; i+start <= s.length()&&i<=3; i++) {//最大是3位数
            int num ;
            if(path.size()<3){
                num = Integer.parseInt(s.substring(start, i+start));
            }else {//已截取出三个整数,最后部分形成第四个整数
                if (s.charAt(start) == '0'&&start!=s.length()-1) {//整数不可以0开头
                    return;
                }
                if(s.length()-start>3) return;//不可超过3位数
                num = Integer.parseInt(s.substring(start));
                i=s.length()-start;
            }
            if(num==0){//整数不可以0开头,只能截取数字“0”,故不再循环后面的截取
                path.add(num);
                dfsRestoreIpAddresses(s, res, path, start+i);
                path.removeLast();
                return;
            }else if(num<=255&&num>0){
                path.add(num);
                dfsRestoreIpAddresses(s, res, path, start+i);
                path.removeLast();
            }else {//截取超出范围,不再执行
                return;
            }
        }
    }
posted @ 2025-02-16 14:49  123木头人-10086  阅读(18)  评论(0)    收藏  举报