代码随想录算法训练营 day 28: ● 93.复原IP地址 ● 78.子集 ● 90.子集II

71 阅读1分钟

93. Restore IP Addresses

这题跟回文子串差不多。但要注意非法IP 取值

  1. 首位为0的多位数不合法,若为0则只能单独占一位,013是不允许的。
  2. 负数不合法(题目已排除)
  3. 超过255的数字不合法。
class Solution {
    public void backtracking(LinkedList<String> path, String str, int pos, List<String> res) {
        if(pos == str.length() && path.size() == 4) {
            //finished output
            res.add(String.join(".", path));
            return;
        }

        if(path.size() >= 4) {
            return;
        }

        for(int i=pos; i<str.length() && i-pos+1 <= 3; i++) {
            //handle 0 start
            boolean toQuit = false;
            if(str.charAt(pos) == '0') {
                toQuit = true;
            }

            String left_s = str.substring(pos, i+1);
            int left = Integer.parseInt(left_s);

            if(left >= 0 && left <= 255) {
                path.add(left_s);
                backtracking(path, str, i+1, res);
                path.removeLast();
            }

            if(toQuit) {
                break;
            }

        }
    }
    public List<String> restoreIpAddresses(String s) {
        List<String> res = new LinkedList<String>();
        LinkedList<String> path = new LinkedList<String>();

        if(s.length() == 0) {
            return res;
        }

        backtracking(path, s, 0, res);

        return res;
    }
}

78. Subsets

这题想麻烦了,钻进了死胡同,还照着切割的思路做。肯定是不对的。 要注意子集有点像组合,但也不太一样。收集结果的操作没有条件,要在回溯最前

class Solution {
    public void backtracking(LinkedList<Integer> path, int[] nums, int pos, List<List<Integer>> res) {
        res.add(new LinkedList<Integer>(path));
        if(pos >= nums.length) {
            return;
        }

        for(int i=pos; i<nums.length; i++) {

            path.add(nums[i]);
            backtracking(path, nums, i+1, res);
            path.removeLast();
        }
    }
    public List<List<Integer>> subsets(int[] nums) {
        List<List<Integer>> res = new LinkedList<List<Integer>>();
        LinkedList<Integer> path = new LinkedList<Integer>();

        //res.add(Collections.<Integer>emptyList());

        backtracking(path, nums, 0, res);

        return res;
        
    }
}

90. Subsets II 需要去重的子集问题。要注意:

  1. 去重逻辑跟组合去重一样
  2. 去重必须先排序。
class Solution {
    public void backtracking(LinkedList<Integer> path, int[] nums, int pos, List<List<Integer>> res) {
        res.add(new LinkedList<Integer>(path));

        if(pos >= nums.length) {
            return;
        }

        for(int i=pos; i<nums.length; i++) {
            if(i>0 && i>pos && nums[i] == nums[i-1]) {
                continue;
            }
            path.add(nums[i]);
            backtracking(path, nums, i+1, res);
            path.removeLast();
        }
    }
    public List<List<Integer>> subsetsWithDup(int[] nums) {
        List<List<Integer>> res = new LinkedList<List<Integer>>();
        LinkedList<Integer> path = new LinkedList<Integer>();

        Arrays.sort(nums);

        backtracking(path, nums, 0, res);

        return res;
    }
}