代码随想录day28

93.复原IP地址

● 力扣题目链接
● 给定一个只包含数字的字符串,复原它并返回所有可能的 IP 地址格式。
● 有效的 IP 地址 正好由四个整数(每个整数位于 0 到 255 之间组成,且不能含有前导 0),整数之间用 ‘.’ 分隔。

思路

● 拿到一个字符串,搜索看符合要求的IP地址
● 进入递归函数,如果分隔符为三个,看看最后一部分是否有效,如果有效就找到了,加入res中
● 循环遍历字符串,如果某段是有效的,就在s中加分隔符,计数+1,然后继续查找,回溯回来记得减去计数并复原字符串

代码

class Solution {
    List<String> res = new ArrayList();
    public List<String> restoreIpAddresses(String s) {
        if (s.length() > 12) return res;
        restoreIpAddressesHelper(s, 0, 0);
        return res;
    }
    private void restoreIpAddressesHelper(String s, int startIndex, int num) {
        if (num == 3) { // 分隔符数量为3,可能进行收集
            if (isValid(s, startIndex, s.length() - 1)) { // 最后一部分有效
                res.add(s); // 加入
            }
            return;
        }
        for (int i = startIndex; i < s.length(); i++) {
            if (isValid(s, startIndex, i)) { // 这部分有效
                s = s.substring(0, i + 1) + "." + s.substring(i + 1); // 字符串加分隔符
                num++; // 数量+1
                restoreIpAddressesHelper(s, i + 2, num); // 递归
                num--;
                s = s.substring(0, i + 1) + s.substring(i + 2);
            } else {
                break;
            }
        }
    }
    // 判断字符串的某部分是否有效
    private boolean isValid(String s, int start, int end) {
        if (start > end) return false; // 头大于尾,无效
        if (start != end && s.charAt(start) == '0') return false; // 0开头无效
        int num = 0;
        for (int i = start; i <= end; i++) {
            if (s.charAt(i) > '9' || s.charAt(i) < '0') return false; // 特殊字符无效
            num = num * 10 + (s.charAt(i) - '0'); // 计算num
        }
        if (num > 255) return false; // 数字大于255无效
        return true;
    }
}

78.子集

● 力扣题目链接
● 给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。
● 说明:解集不能包含重复的子集。

思路

● 还是组合问题,因为没有顺序,需要注意的是,每个元素都要加进去

代码

class Solution {
    List<List<Integer>> res = new ArrayList();
    Deque<Integer> path = new ArrayDeque();
    public List<List<Integer>> subsets(int[] nums) {
        subsetsHelper(nums, 0);
        return res;
    }
    private void subsetsHelper(int[] nums, int startIndex) {
        res.add(new ArrayList<>(path)); // 每个都要加进去
        for (int i = startIndex; i < nums.length; i++) {
            path.addFirst(nums[i]);
            subsetsHelper(nums, i + 1); // 还是回溯
            path.removeFirst();
        }
    }
}

90.子集II

● 力扣题目链接
● 给定一个可能包含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。
● 说明:解集不能包含重复的子集。

思路

● 考虑同层的去重逻辑,以及子集问题,所有都要收集

代码

class Solution {
    List<List<Integer>> res = new ArrayList();
    Deque<Integer> path = new ArrayDeque();
    public List<List<Integer>> subsetsWithDup(int[] nums) {
        Arrays.sort(nums);
        subsetsWithDupHelper(nums, 0);
        return res;
    }
    private void subsetsWithDupHelper(int[] nums, int startIndex) {
        res.add(new ArrayList<>(path));
        for (int i = startIndex; i < nums.length; i++) {
            if (i > startIndex && nums[i] == nums[i - 1]) continue;
            path.addFirst(nums[i]);
            subsetsWithDupHelper(nums, i + 1);
            path.removeFirst();
        }
    }
}

你可能感兴趣的:(代码随想录,java,算法,数据结构)