算法通关村第18关【黄金】| 继续回溯

1.复原IP地址

思路:

单层for循环start控制开始位置,逐个遍历情况取,附带剪枝,递归返回后进行point回溯

深度递归pointNum三层,确定终止条件

java 复制代码
class Solution {
    List<String> result = new ArrayList<>();
    public List<String> restoreIpAddresses(String s) {
        if(s.length()>12){
            return result;
        }
        trace(s,0,0);
        return result;
    }
    
    public void trace(String s,int start,int pointNum){
        if(pointNum == 3){
            if (isValid(s,start,s.length()-1)) {
                result.add(s);
            }
            return;
        }
        for(int i = start;i<s.length();i++){
            if(isValid(s,start,i)){
                pointNum++;
                s = s.substring(0,i+1) + "." + s.substring(i+1);
                trace(s,i+2,pointNum);
                pointNum--;// 回溯
                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 (s.charAt(start) == '0' && start != end) { // 0开头的数字不合法
            return false;
        }
        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');
            if (num > 255) { // 如果⼤于255了不合法
                return false;
            }
        }
        return true;
    }
}

2.电话号码的字母组合

思路:回溯模板

层的选择元素为c[num],for(int i = 0;i<c[num-2].length;i++),组合不需要剪枝

深度为digits的长度,确定终止条件

java 复制代码
class Solution {
    public List<String> letterCombinations(String digits) {
        List<String> list = new ArrayList<String>();
        if(digits.length() == 0){
            return list;
        }
        char[][] c = {
            {'a','b','c'},
            {'d','e','f'},
            {'g','h','i'},
            {'j','k','l'},
            {'m','n','o'},
            {'p','q','r','s'},
            {'t','u','v'},
            {'w','x','y','z'}
        };
        int len = digits.length();
        char[] s = new char[len];
        trace(c,s,list,0,digits);
        return list;

    }
    public void trace(char[][] c,char[] s,List list,int cur,String digits){
        if(cur == s.length){
            list.add(new String(s));
            return;
        }
        int num = digits.charAt(cur) - '0';
        for(int i = 0;i<c[num-2].length;i++){
            num = digits.charAt(cur) - '0';
            s[cur] = c[num-2][i];
            trace(c,s,list,cur+1,digits);

        }
    }
}

3.括号生成

思路:回溯

层的选择元素有两个 '(' ,')',但是不能瞎选需要满足题目要求也就是要进行剪枝

  • 剩余左括号数量要小于等于右括号数量
  • 剩余的括号数量要大于0

由深度也就是n*2总共长度,确定终止条件

java 复制代码
class Solution {
    public List<String> generateParenthesis(int n) {
        List<String> list = new ArrayList<>();
        char[] s = new char[n*2];
        trace(n,n,s,list,0);
        return list;
    }

    public void trace(int left,int rigth,char[] s,List list,int cur){
        if(left == 0 && rigth == 0){
            list.add(new String(s));
            return;
        }
        if(left-1>=0&&left-1<=rigth){
            s[cur] = '(';
            trace(left-1,rigth,s,list,cur+1);
        }
        if(rigth-1>=0&&left<=rigth-1){
            s[cur] = ')';
            trace(left,rigth-1,s,list,cur+1);
        }
    }
}
相关推荐
workflower3 小时前
单元测试-例子
java·开发语言·算法·django·个人开发·结对编程
MicroTech20255 小时前
微算法科技(MLGO)研发突破性低复杂度CFG算法,成功缓解边缘分裂学习中的掉队者问题
科技·学习·算法
墨染点香5 小时前
LeetCode 刷题【126. 单词接龙 II】
算法·leetcode·职场和发展
aloha_7896 小时前
力扣hot100做题整理91-100
数据结构·算法·leetcode
Tiny番茄6 小时前
31.下一个排列
数据结构·python·算法·leetcode
挂科是不可能出现的6 小时前
最长连续序列
数据结构·c++·算法
前端小L7 小时前
动态规划的“数学之魂”:从DP推演到质因数分解——巧解「只有两个键的键盘」
算法·动态规划
RTC老炮7 小时前
webrtc弱网-ReceiveSideCongestionController类源码分析及算法原理
网络·算法·webrtc
21号 17 小时前
9.Redis 集群(重在理解)
数据库·redis·算法
hadage2339 小时前
--- 数据结构 AVL树 ---
数据结构·算法