算法通关村第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);
        }
    }
}
相关推荐
多打代码22 分钟前
2025.09.05 用队列实现栈 & 有效的括号 & 删除字符串中的所有相邻重复项
python·算法
j_xxx404_2 小时前
数据结构:栈和队列力扣算法题
c语言·数据结构·算法·leetcode·链表
南莺莺2 小时前
假设一个算术表达式中包含圆括号、方括号和花括号3种类型的括号,编写一个算法来判别,表达式中的括号是否配对,以字符“\0“作为算术表达式的结束符
c语言·数据结构·算法·
THMAIL2 小时前
深度学习从入门到精通 - 神经网络核心原理:从生物神经元到数学模型蜕变
人工智能·python·深度学习·神经网络·算法·机器学习·逻辑回归
野犬寒鸦2 小时前
力扣hot100:旋转图像(48)(详细图解以及核心思路剖析)
java·数据结构·后端·算法·leetcode
墨染点香2 小时前
LeetCode 刷题【61. 旋转链表】
算法·leetcode·职场和发展
一枝小雨3 小时前
【OJ】C++ vector类OJ题
数据结构·c++·算法·leetcode·oj题
Tisfy3 小时前
LeetCode 3516.找到最近的人:计算绝对值大小
数学·算法·leetcode·题解
自信的小螺丝钉3 小时前
Leetcode 206. 反转链表 迭代/递归
算法·leetcode·链表
黑色的山岗在沉睡4 小时前
LeetCode 189. 轮转数组
java·算法·leetcode