• 代码随想录算法训练营第28天|93.复原IP地址 78.子集 90.子集II


    JAVA代码编写

    93 .复原IP地址

    有效 IP 地址 正好由四个整数(每个整数位于 0255 之间组成,且不能含有前导 0),整数之间用 '.' 分隔。

    • 例如:"0.1.2.201" "192.168.1.1"有效 IP 地址,但是 "0.011.255.245""192.168.1.312""192.168@1.1"无效 IP 地址。

    给定一个只包含数字的字符串 s ,用以表示一个 IP 地址,返回所有可能的有效 IP 地址,这些地址可以通过在 s 中插入 '.' 来形成。你 不能 重新排序或删除 s 中的任何数字。你可以按 任何 顺序返回答案。

    示例 1:

    输入:s = "25525511135"
    输出:["255.255.11.135","255.255.111.35"]
    
    • 1
    • 2

    示例 2:

    输入:s = "0000"
    输出:["0.0.0.0"]
    
    • 1
    • 2

    示例 3:

    输入:s = "101023"
    输出:["1.0.10.23","1.0.102.3","10.1.0.23","10.10.2.3","101.0.2.3"]
    
    • 1
    • 2

    提示:

    • 1 <= s.length <= 20
    • s 仅由数字组成

    教程:https://programmercarl.com/0093.%E5%A4%8D%E5%8E%9FIP%E5%9C%B0%E5%9D%80.html

    方法一:回溯

    思路

    93.复原IP地址

    class Solution {
        List<String> result = new ArrayList<String>();
    	StringBuilder stringBuilder = new StringBuilder();
    
    	public List<String> restoreIpAddresses(String s) {
    		restoreIpAddressesHandler(s, 0, 0);
    		return result;
    	}
    
    	// number表示stringbuilder中ip段的数量
    	public void restoreIpAddressesHandler(String s, int start, int number) {
    		// 如果start等于s的长度并且ip段的数量是4,则加入结果集,并返回
    		if (start == s.length() && number == 4) {
    			result.add(stringBuilder.toString());
    			return;
    		}
    		// 如果start等于s的长度但是ip段的数量不为4,或者ip段的数量为4但是start小于s的长度,则直接返回
    		if (start == s.length() || number == 4) {
    			return;
    		}
    		// 剪枝:ip段的长度最大是3,并且ip段处于[0,255]
    		for (int i = start; i < s.length() && i - start < 3 && Integer.parseInt(s.substring(start, i + 1)) >= 0
    				&& Integer.parseInt(s.substring(start, i + 1)) <= 255; i++) {
    			// 如果ip段的长度大于1,并且第一位为0的话,continue
    			if (i + 1 - start > 1 && s.charAt(start) - '0' == 0) {
    				continue;
    			}
    			stringBuilder.append(s.substring(start, i + 1));
    			// 当stringBuilder里的网段数量小于3时,才会加点;如果等于3,说明已经有3段了,最后一段不需要再加点
    			if (number < 3) {
    				stringBuilder.append(".");
    			}
    			number++;
    			restoreIpAddressesHandler(s, i + 1, number);
    			number--;
    			// 删除当前stringBuilder最后一个网段,注意考虑点的数量的问题
    			stringBuilder.delete(start + number, i + number + 2);
    		}
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40

    78. 子集

    给你一个整数数组 nums ,数组中的元素 互不相同 。返回该数组所有可能的子集(幂集)。

    解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。

    示例 1:

    输入:nums = [1,2,3]
    输出:[[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]]
    
    • 1
    • 2

    示例 2:

    输入:nums = [0]
    输出:[[],[0]]
    
    • 1
    • 2

    提示:

    • 1 <= nums.length <= 10
    • -10 <= nums[i] <= 10
    • nums 中的所有元素 互不相同

    教程:https://programmercarl.com/0078.%E5%AD%90%E9%9B%86.html

    方法一:回溯

    思路

    78.子集

    class Solution {
        List<List<Integer>> result = new ArrayList<>();// 存放符合条件结果的集合
        LinkedList<Integer> path = new LinkedList<>();// 用来存放符合条件结果
        public List<List<Integer>> subsets(int[] nums) {
            subsetsHelper(nums, 0);
            return result;
        }
    
        private void subsetsHelper(int[] nums, int startIndex){
            result.add(new ArrayList<>(path));//「遍历这个树的时候,把所有节点都记录下来,就是要求的子集集合」。
            if (startIndex >= nums.length){ //终止条件可不加
                return;
            }
            for (int i = startIndex; i < nums.length; i++){
                path.add(nums[i]);
                subsetsHelper(nums, i + 1);
                path.removeLast();
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    90. 子集 II

    给你一个整数数组 nums ,其中可能包含重复元素,请你返回该数组所有可能的子集(幂集)。

    解集 不能 包含重复的子集。返回的解集中,子集可以按 任意顺序 排列。

    示例 1:

    输入:nums = [1,2,2]
    输出:[[],[1],[1,2],[1,2,2],[2],[2,2]]
    
    • 1
    • 2

    示例 2:

    输入:nums = [0]
    输出:[[],[0]]
    
    • 1
    • 2

    提示:

    • 1 <= nums.length <= 10
    • -10 <= nums[i] <= 10

    教程:https://programmercarl.com/0090.%E5%AD%90%E9%9B%86II.html

    方法一:回溯

    思路

    90.子集II

    class Solution {
       List<List<Integer>> result = new ArrayList<>();// 存放符合条件结果的集合
       LinkedList<Integer> path = new LinkedList<>();// 用来存放符合条件结果
       boolean[] used;
        public List<List<Integer>> subsetsWithDup(int[] nums) {
            if (nums.length == 0){
                result.add(path);
                return result;
            }
            Arrays.sort(nums);
            used = new boolean[nums.length];
            subsetsWithDupHelper(nums, 0);
            return result;
        }
        
        private void subsetsWithDupHelper(int[] nums, int startIndex){
            result.add(new ArrayList<>(path));
            if (startIndex >= nums.length){
                return;
            }
            for (int i = startIndex; i < nums.length; i++){
                if (i > 0 && nums[i] == nums[i - 1] && !used[i - 1]){
                    continue;
                }
                path.add(nums[i]);
                used[i] = true;
                subsetsWithDupHelper(nums, i + 1);
                path.removeLast();
                used[i] = false;
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
  • 相关阅读:
    自定义注解,利用AOP实现日志保存(数据库),代码全贴,复制就能用
    C++11之追踪返回类型
    自研 MySQL Binlog 分析程序介绍
    “Flash闪存”基础 及 “SD NAND Flash”产品的测试
    力扣刷题--数组1
    MySQL视图、用户管理
    咖啡餐饮PPT模板
    《javascript忍者秘籍》笔记
    【手把手带你学会KMP算法】
    citavi合并重复文献题录
  • 原文地址:https://blog.csdn.net/Catherinemin/article/details/134538658