算法训练营第二十八天|93.复原IP地址、78.子集、90.子集II

42 阅读1分钟

93. 复原 IP 地址

131. 分割回文串的基础上,将判断回文串的逻辑修改为判断合法IP的逻辑即可。

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

    public List<String> restoreIpAddresses(String s) {
        backtrack(s, 0);
        return res;
    }
    private void backtrack(String s, int start){
        if(start == s.length() && path.size() == 4){
            res.add(String.join(".", path));
            return;
        }

        for(int i = start; i < s.length(); i++){
            if(!isValid(s, start, i)){
                continue;
            }
            if(path.size() >= 4){
                break;
            }

            path.add(s.substring(start, i + 1));
            backtrack(s, i + 1);
            path.removeLast();
        }
    }

    private boolean isValid(String s, int start, int end){
        int length = end - start + 1;
        if(length == 0 || length > 3){
            return false;
        }
        if(length == 1)return true; // 只有一位数字肯定是合法的
        else if(s.charAt(start) == '0')return false; // 多于一位数字,但开头是0,肯定不合法
        else if(length == 2)return true; // 排除了开头是0和只有一位的情况,如果长度是两位,是合法的
        else if(Integer.parseInt(s.substring(start, start + length)) > 255)return false; // 现在输入的一定是三位数
        else return true;
    }
}

78. 子集

class Solution {
    LinkedList<Integer> path = new LinkedList<>();
    List<List<Integer>> res = new LinkedList<>();
    public List<List<Integer>> subsets(int[] nums) {
        backtrack(nums, 0);
        return res;
    }
    private void backtrack(int[] nums, int start){
        res.add(new LinkedList<>(path));

        for(int i = start; i < nums.length; i++){
            path.add(nums[i]);
            backtrack(nums, i + 1);
            path.removeLast();
        }
    }
}

90. 子集 II

class Solution {
    LinkedList<Integer> path = new LinkedList<>();
    List<List<Integer>> res = new LinkedList<>();
    public List<List<Integer>> subsetsWithDup(int[] nums) {
        Arrays.sort(nums);
        backtrack(nums, 0);
        return res;
    }
    private void backtrack(int[] nums, int start){
        res.add(new LinkedList<>(path));

        for(int i = start; i < nums.length; i++){
            if(i > start && nums[i] == nums[i - 1])continue;

            path.add(nums[i]);
            backtrack(nums, i + 1);
            path.removeLast();
        }
    }
}