leetcode回溯算法刷题总结

leetcode之回溯刷题总结1 leetcode之回溯刷题总结1 回溯法:一种通过探索所有可能的候选解来找出所有的解的算法。如果候选解被确认不是一个解(或者至少不是最后一个解),回溯算法会通过在上一步进行一些变化抛弃该解,即回溯并且再次尝试。 1-全排列 题目链接:题目链接戳这里!!! 思路:这个问题可以看作有 n 个排列成一行的空格,我们需要从左往右依此填入题目给定的 n 个数,每个数只能使用一次。那么很直接的可以想到一种穷举的算法,即从左往右每一个位置都依此尝试填入一个数,看能不能填完这 n 个空格,在程序中我们可以用「回溯法」来模拟 阅读详情

刷题大纲

在这里插入图片描述
组合问题:N个数里面按一定规则找出k个数的集合
切割问题:一个字符串按一定规则有几种切割方式
子集问题:一个N个数的集合里有多少符合条件的子集
排列问题:N个数按一定规则全排列,有几种排列方式
棋盘问题:N皇后,解数独等等

核心模板

定义两个变量 一个记录路径path 一个为最终结果result
在这里插入图片描述
1. 终止条件是什么
(1)一般是path.size()
(2)取所有结果的不需要终止条件
2. for循环 是从0开始 还是从startIndex开始(取过的不能再取了,跟顺序无关[1,2] [2,1]算一种情况)
3. backTracking函数返回值是什么 结果唯一,返回Boolean
4. 调用递归函数backTracking函数的参数
5. 是否需要去重
6. 涉及到需要k个数的 可以考虑剪枝优化,对i的范围进一步限制

整体套路

画树形结构,for表示横向遍历,for的内容表示深度,分析上面问题------------------创建path result变量---------------------------------套模板

一、子集问题

78 子集(简单回溯)

在这里插入图片描述
求所有可能且无限制不需要终止条件
跟顺序无关,1,2和2,1表示同一个,因此每次index+1开始遍历

class Solution {
    List<List<Integer>> result = new ArrayList<>();
    LinkedList<Integer> path = new LinkedList<>();
    public List<List<Integer>> subsets(int[] nums) {
        backTracking(nums,0);
        return result;
    }
    public void backTracking(int[] nums,int startIndex){
        result.add(new ArrayList<>(path));
        for(int i = startIndex;i<nums.length;i++){  
            path.add(nums[i]); 
            backTracking(nums,i+1);
            path.removeLast();  
        }
   }

90 子集2 (需要去重)

在这里插入图片描述
先排序,后去重: 当前元素与上一个元素相同
去重是在横向方向for循环上去重

class Solution {
    List<List<Integer>> result = new ArrayList<>();
    LinkedList<Integer> path = new LinkedList<>();
    public List<List<Integer>> subsetsWithDup(int[] nums) {
        Arrays.sort(nums);
        backTracking(nums,0);
        return result;
    }
    public void backTracking(int[] nums, int startIndex){
        result.add(new ArrayList<>(path));
        for(int i = startIndex; i <nums.length;i++){
            if (i> startIndex && nums[i]==nums[i-1]){
                continue;
            }
            path.add(nums[i]);
            backTracking(nums,i+1);
            path.removeLast();
        }
    }
}

二、组合问题

77 组合(常规回溯+剪枝优化)

在这里插入图片描述
限制i的范围进行剪枝优化

class Solution {
    List<List<Integer>> result = new ArrayList<>();
    LinkedList<Integer> path = new LinkedList<>();
    // List<Integer> path = new LinkedList<>();
    public List<List<Integer>> combine(int n, int k) {
        backTrack(n,k,1);
        return result;

        }
    public void backTrack(int n,int k, int startIndex){
        if (path.size() == k){//终止条件:path的大小与所给一致
            result.add(new ArrayList<>(path));
            return;
        }
        for (int i = startIndex; i<=n-(k-path.size())+1; i++){ //剪枝优化:必须有足够多的数满足
            path.add(i);
            backTrack(n,k,i+1); //递归函数要+1
            path.removeLast();
        }
    }
}

17 电话号码的字母组合(回溯+建立数字和字母映射关系)

在这里插入图片描述
画出树形结构
for循环的是每个数字对应的字母
遍历深度的是 所给字符串
把数字和字母对应起来

在这里插入图片描述

class Solution {
    List<String> result = new ArrayList<>();
    StringBuilder temp = new StringBuilder();
    public List<String> letterCombinations(String digits) {
        if (digits.length() == 0 || digits == null){
            return result;
        }
        
        String[] numStr = {"","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"}; //需要把数字映射到字符串上
        backTracking(digits, numStr, 0);
        return result;

    }
    public void backTracking(String digits,String[] numStr, int index){
        if (index == digits.length()){
            result.add(temp.toString());// 把列表变为字符串
            return;
        }
        String str = numStr[digits.charAt(index) - '0'];
        for (int i = 0; i < str.length(); i++){
            temp.append(str.charAt(i));
            backTracking(digits,numStr,index+1);
            temp.deleteCharAt(temp.length()-1);
        }

    }
}

39 组合总和( 所给数组无重复元素 + 同一数字无限制重复选取)

在这里插入图片描述
在这里插入图片描述

class Solution {
    List<List<Integer>> result = new ArrayList<>();
    LinkedList<Integer> path = new LinkedList<>();
    public List<List<Integer>> combinationSum(int[] candidates, int target) {

        backTracking(candidates,target,0,0);
        return result;
    }
    public void backTracking(int[] candidates, int target, int sum, int index){
        if (sum > target){
            return;
        }
        if (sum == target){
            result.add(new ArrayList<>(path));
            return;
        }
        for (int i = index; i < candidates.length;i++){  //搜索过的不需要再搜索
            sum += candidates[i];
            path.add(candidates[i]);
            backTracking(candidates,target,sum,i);  //遍历是从i开始 
            sum -= candidates[i];
            path.removeLast();
        }
    }
}

backTracking(candidates,target,sum,i)注意此处不需要i+1,且for循环从index开始

40 组合总和 Ⅱ (给定集合存在重复数字 + 每个数字只能使用一次, 需要去重)

在这里插入图片描述
在这里插入图片描述

class Solution {
    List<List<Integer>> result = new ArrayList<>();
    LinkedList path = new LinkedList<>(); 
    public List<List<Integer>> combinationSum2(int[] candidates, int target) {
        Arrays.sort(candidates);
        backTracking(candidates,target,0,0);
        return result;
    }
    public void backTracking(int[] candidates, int target,int sum,int index){
        if (sum > target){
            return;//深度上剪枝
        }
        if (sum == target){
            result.add(new ArrayList<>(path));
        }
        for (int i = index; i<candidates.length;i++){
            if (i>index && candidates[i] == candidates[i-1]){
                continue;//宽度上剪枝
            }
            sum += candidates[i];
            path.add(candidates[i]);
            backTracking(candidates,target,sum,i+1);
            sum -= candidates[i];
            path.removeLast();
        }
    }
}

216 组合总和 Ⅲ (回溯 + 剪枝)

在这里插入图片描述
在这里插入图片描述

class Solution {
    List<List<Integer>> result = new ArrayList<>();
    LinkedList<Integer> path = new LinkedList<>();
    public List<List<Integer>> combinationSum3(int k, int n) {
        backTrack(k,n,1,0);
        return result;
    }
    public void backTrack(int k,int n,int startIndex,int sum){
        if (sum > n){ //深度剪枝
            return;
        }
        if (path.size()==k){
            if (sum == n){
                result.add(new ArrayList<>(path));
                return;
            }
        }
        for (int i=startIndex; i <= 9-(k-path.size())+1; i++){ //宽度剪枝:数目不够
            sum += i;
            path.add(i);
            backTrack(k,n,i+1,sum);
            sum -= i;
            path.removeLast();
            
        }
    }
}

三、排列问题

46.全排列

在这里插入图片描述
引入一个used数组记录已经使用过的元素即可

class Solution {
    List<List<Integer>> result = new ArrayList<>();
    LinkedList<Integer> path = new LinkedList<>();
    boolean[] used;
    public List<List<Integer>> permute(int[] nums) {
        used = new boolean[nums.length];     

        backTracking(nums);
        return result;   
    }
    public void backTracking(int[] nums){
        if (path.size() == nums.length){
            result.add(new ArrayList<>(path));
            return;
        }
        for(int i =0;i<nums.length;i++){
            if (used[i] == true){
                continue;
            }
            used[i] = true;
            path.add(nums[i]);
            backTracking(nums);
            path.removeLast();
            used[i] = false;
        }
    }
}

47.全排列Ⅱ(宽度上进行去重)

在这里插入图片描述
在这里插入图片描述

class Solution {
    List<List<Integer>> result = new ArrayList<>();
    LinkedList<Integer> path = new LinkedList<>();
    boolean[] used;
    public List<List<Integer>> permuteUnique(int[] nums) {
        Arrays.sort(nums);
        used = new boolean[nums.length];     
        backTracking(nums);
        return result;  
    }
    public void backTracking(int[] nums){
        if (path.size() == nums.length){
            result.add(new ArrayList<>(path));
            return;
        }
        
        for(int i =0;i<nums.length;i++){
            if (used[i] == true){
                continue;
            }
            if (i>0 && nums[i-1] == nums[i] && used[i-1]==true){
                continue;
            }//在宽度上进行去重 而深度上可以出现重复的元素
            used[i] = true;
            path.add(nums[i]);
            backTracking(nums);
            path.removeLast();
            used[i] = false;
        }
    }
}

四、分割问题

131.分割回文串

在这里插入图片描述
类似组合问题,先求出分割的可能性,再判断是否为回文串
在这里插入图片描述
(1) if 终止条件: 切割线大于字符串长度
(2) 取过的元素不能再取了 for开始遍历的坐标为startIndex
(3) 子串的位置为 startIndex,i+1

class Solution {
    List<List<String>> result = new ArrayList<>();
    LinkedList<String> path = new LinkedList<>();
    public List<List<String>> partition(String s) {
        backTracking(s,0);
        return result;
    }
    public void backTracking(String s, int startIndex){
        if (startIndex >= s.length()){
            result.add(new ArrayList<>(path));
            return;
        }
        //for为横向遍历
        //递归为纵向遍历
        for (int i = startIndex;i<s.length();i++){
            if ( isPalindrom(s,startIndex,i)){//横向遍历
                String str = s.substring(startIndex,i+1);//取子串
                path.add(str);
            }
            else{continue;}
            backTracking(s, i + 1);
            path.removeLast();
        }
    }
    //判断回文
    public boolean isPalindrom(String s,int startIndex,int endIndex){
        for (int i = startIndex, j = endIndex;i<j;i++,j--){
            if(s.charAt(i) != s.charAt(j)){
                return false;
            }
        }
        return true;
    }
}

93.复原ip地址

在这里插入图片描述
在这里插入图片描述
(1) if终止条件: 点数 数量为3
(2) for循环 起始位置 startIndex
(3) string.substring 取子串函数
s.charAt(i) 按索引取元素

class Solution {
    List<String> result = new ArrayList<>();
    public List<String> restoreIpAddresses(String s) {
        if (s.length() > 12) {
            return result;
        } //长度最大为12
        backTracking(s,0,0);
        return result;
    }
    public void backTracking(String s, int  startIndex, int pointNum){
        if (pointNum == 3){
            if (isValid(s,startIndex,s.length()-1)){
                result.add(s);
            }
            return;
        }
        for (int i=startIndex;i<s.length();i++){
            if (isValid(s,startIndex,i)){
                s = s.substring(0,i+1) + '.' + s.substring(i+1);
                pointNum++;
                backTracking(s,i+2,pointNum);//加了分隔号 i+2
                pointNum--;
                s = s.substring(0,i+1) + s.substring(i+2);
            }
            else{break;}
        }
    }
    //判断是否符合要求
    public Boolean isValid(String s, int start, int end){
        if (start>end){
            return false;
        } 
        if (s.charAt(start) == '0' && start != end){
            return false; //前导不能为0
        }
        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){
                return false;
            }
        }
        return true;
    }
}

五.棋盘问题

51.N皇后

在这里插入图片描述
棋盘的宽度就是for循环的长度,递归的深度就是棋盘的高度
for循环从0开始
游戏规则
不能同行
不能同列
不能同斜线 (45度和135度角)
在这里插入图片描述

class Solution {
    List<List<String>> result = new ArrayList<>();
    public List<List<String>> solveNQueens(int n) {
        //初始化一个二维数组 模拟棋盘
        char[][] chessboard = new char[n][n];
        for (char[] c:chessboard){//记住写法
            Arrays.fill(c,'.');
        }
        //调用回溯函数
        backTracking(n,0,chessboard);
        return result;
    }
    public void backTracking(int n, int row, char[][] chessboard){
        if (row == n){
            List<String> path = new ArrayList<>();
            path = Array2List(chessboard);               //把二维数组变成yi维数组
            result.add(new ArrayList<>(path)); //添加结果
            return;
        }
        for (int col = 0; col < n; col++){//列遍历 即宽度
            if (isValid(n,row,col,chessboard)){//判断是否合法
                chessboard[row][col] = 'Q';
                backTracking(n, row+1, chessboard);
                chessboard[row][col] = '.';
            }
        }
    }
    //把二维棋盘变为一维数组
    public List<String> Array2List(char[][] chessboard){
        List<String> path = new ArrayList<>();
        for (char[] c:chessboard){//注意此格式
            path.add(String.copyValueOf(c));
        }
        return path;
    }
    //判断是否合法 已知棋子的行和列
    public boolean isValid(int n,int row,int col,char[][] chessboard){
//列:每一列不能出现相同的  如果该列已经存在Q了 那么将不能再放Q 即固定列 从第0行开始遍历到row行 不能出现Q
        for(int i = 0; i < row; i++){
           if(chessboard[i][col] == 'Q'){
               return false;
           } 
        }
//检查45对角线:检查 row行 col列左上角 不能存在Q
        for (int i=row-1, j=col-1; i>=0 && j>=0; i--, j--) {
            if (chessboard[i][j] == 'Q') {
                return false;
            }
        }
 // 检查135度对角线 右上角
        for (int i=row-1, j=col+1; i>=0 && j<=n-1; i--, j++) {
            if (chessboard[i][j] == 'Q') {
                return false;
            }
        }
        return true;
    }

37.解数独

在这里插入图片描述
一个for循环遍历棋盘的行,一个for循环遍历棋盘的列,一行一列确定下来之后,递归遍历这个位置放9个数字的可能性!
回溯函数返回值必须为boolean

class Solution {
    public void solveSudoku(char[][] board) {
        backTracking(board);
    }
    public boolean backTracking(char[][] board) {
        for(int i =0;i<9;i++){//行
            for(int j=0;j<9;j++){//列遍历
                if(board[i][j] != '.'){continue;}
                for (char c ='1';c<='9';c++){
                    if (isVailid(i,j,c,board)){
                        board[i][j] = c;
                        if(backTracking(board)) {return true;}
                        board[i][j] = '.';
                    }
                }
                return false;
            }              
        }
        return true;
    }
    public boolean isVailid(int i,int j,char c,char[][] board){
//行:重复
        for(int col=0;col<9;col++){
            if (board[i][col] == c){
                return false;
            }
        }
//列:重复
        for (int row=0;row<9;row++){
            if (board[row][j] == c){
                return false;
            }
        }
//九宫格
        int startRow = (i / 3) * 3;
        int startCol = (j / 3) * 3;
        for (int p = startRow; p <= startRow+2; p++){
            for (int q = startCol; q<=startCol+2;q++){
                if(board[p][q] == c){
                    return false;
                }
            }
        }
        return true;
    }
}

六、其他问题

491. 递增子序列

在这里插入图片描述
在这里插入图片描述
(1)if终止条件:path大于2
(2)for循环从startIndex开始
(3)去重 用hashmap (难点在于 同一层如何去重)

class Solution {
    List<List<Integer>> result = new ArrayList<>();
    LinkedList<Integer> path = new LinkedList<>();
    public List<List<Integer>> findSubsequences(int[] nums) {
        backTracking(nums,0);
        return result;
    }
    public void backTracking(int[] nums,int startIndex){
        if (path.size() >= 2){
            result.add(new ArrayList<>(path));
        }
        HashMap<Integer,Integer> map = new HashMap<Integer,Integer>();
        for (int i = startIndex;i<nums.length;i++){
            if ( !path.isEmpty() && nums[i] < path.getLast()){
                continue;   // nums[i] 必须比path现有最后一个元素大
            }
            if (map.containsValue(nums[i]) ){
                continue;
            }
            path.add(nums[i]);
            map.put(i,nums[i]);
            backTracking(nums,i+1);
            path.removeLast();
        }
    }
}

332.重新安排行程

在这里插入图片描述
问题:

  1. 一个行程中,如果航班处理不好容易变成一个圈,成为死循环
    用used[] 记录已经使用过的机票
  2. 有多种解法,字母序靠前排在前面,让很多同学望而退步,如何该记录映射关系呢 ?
    Collections.sort(tickets, (a,b) -> a.get(1).compareTo(b.get(1))) 只要对机票的目的地排序即可
  3. 使用回溯法(也可以说深搜) 的话,那么终止条件是什么呢?
    path.size = 机票数+1
  4. 搜索的过程中,如何遍历一个机场所对应的所有机场。
    机票的第一个元素 == path的最后一个元素
  5. 回溯函数返回值为boolean,路径唯一
class Solution {
    LinkedList<String> path = new LinkedList<>();
    LinkedList<String> result;
    public List<String> findItinerary(List<List<String>> tickets) {
        Collections.sort(tickets, (a,b) -> a.get(1).compareTo(b.get(1)));//排序 按字母排序 写法复杂
        path.add("JFK"); //起点必然为JFK
        boolean[] used = new boolean[tickets.size()];  //记录已经用过的机票
        backTracking(tickets,used);
        return result;
    }
    public boolean backTracking(List<List<String>> tickets,boolean[] used){
        if (path.size() == tickets.size()+1){
            result = new LinkedList(path);
            return true;
        }
        for(int i = 0; i < tickets.size();i++){
            if (!used[i] && tickets.get(i).get(0).equals(path.getLast())){
                path.add(tickets.get(i).get(1));//
                used[i] = true;
                if (backTracking(tickets,used)){
                    return true;
                }
                used[i] = false;
                path.removeLast();

            }
        }
        return false;
    } 
}
2025年GESP3月认证C++五级真题解析 小 A 有 2n 件物品,小 B 和小 C 想从小 A 手上买走这些物品。对于第 i 件物品,小 B 会以 bi 的价格购买,而小 C 会以 ci 的价格购买。对于所有测试点,保证 1 <= T <= 100, 2 <= g < p <= 10^9, g, p 为整数, p 为质数。对于所有测试点,保证 1 <= n <= 10^5, 0 <= bi, ci <= 10^9, bi, ci 为整数。对于另外 50 % 的测试点,保证 n <= 100000, 0 <= bi, ci <= 10^9。 阅读详情

相关推荐

【WSL2+Ubuntu+Docker Desktop】迁移到D盘

该篇文章包含将WSL2+ubuntu+Docker Desktop从C盘迁移到D盘

哈茶的博客 3929

Leetcode刷题总结-4.回溯算法篇

回溯法解决的问题都可以抽象为树形结构,是的,我指的是所有回溯法的问题都可以抽象为树形结构!因为回溯法解决的都是在集合中递归查找子集,集合的大小就构成了树的宽度,递归的深度,都构成的树的深度,递归就要有终止条件,所以必然是一棵高度有限的树(N叉树)。本文主要是分享回溯算法求解问题的思路,回溯算法基本上也是递归三部曲解决,只是有些具体问题需要对细节分析一下。

weixin_44924725的博客 569

密码学实战:如何利用生日攻击破解哈希函数

本文深入探讨了生日攻击在密码学中的应用及其对哈希函数的威胁。通过分析生日悖论的数学原理,揭示了哈希函数在实际应用中的脆弱性,并提供了防御策略,如升级哈希算法、正确使用加盐技术等。文章结合实战案例,帮助开发者理解如何有效防范此类攻击,确保系统安全。

weixin_42530732的博客 191

回溯法刷题入门总结

初看回溯时,觉得超级难以理解,也许是自己太笨了。后来看到大佬的总结,跟着他一步一步从基础题型入手,才慢慢掌握了一点点回溯法的技巧,这里做一个自己的学习总结,凡事还是得脚踏实地一步一步刷起。 如有错误恳请多多指正。 参考:「leetcode」最强回溯算法总结篇!历时21天、画了20张树形结构图、14道精选回溯题目精讲 1.回溯法基本框架 关于回溯法的伪代码,leecode及百度上有很多文章总结过,以c++的vector为例如下 定义 result 数组 定义 path 数组 void backtrack(

qq_35027690的博客 421

海康WEB3.3控件开发包 V3.3 前端vue项目调用实时监控画面

本需求的完成离不开后端将设备映射到公网, 以及前端单独部署demo页面这个思路的转变。

hero8011的博客 1万+

火车头采集器超级详细图文使用指导(面向新手)

火车采集器·超级详细使用指导

DE的个人原创笔记 1万+

【算法】回溯法刷题最全总结

刷题不总结复习,等于白刷。 最近越来越意识到这个道理,于是决定开始把刷过的容易忘记的题总结一下。 一开始看到一些资料中说回溯法是有框架可以遵循的,并不是十分的理解,后来看了几个题目以后,包括dfs的一些题,总算是有了一些体会。 总结一下的框架就是 def backtrace() if 满足条件: 结果中加入track for 选择 in 选择列表: 做选择 backtrace()进入下一级 撤销...

sinat_22078359的博客 458

【Linux内核】Linux内核裁剪完全指南:从理论到实战的系统优化

在嵌入式设备、专用服务器和物联网系统日益普及的今天,如何让Linux系统在资源受限的环境中高效运行成为开发者必须面对的问题。Linux内核裁剪正是解决这一问题的关键技术,它通过移除不必要的内核组件,打造出更精简、更安全、更高效的自定义操作系统。本文将系统全面地介绍Linux内核裁剪的完整流程和实用技巧,帮助您掌握这一核心技能。Linux内核裁剪是一项结合技术知识与实践经验的系统工程。明确需求:裁剪前必须清晰了解目标系统的硬件配置和功能需求。循序渐进:采取小步修改、反复测试的策略,避免一次性大幅修改。

撬动未来的支点的专栏 1387

刷题 回溯算法

文章目录1、字符串的排列(剑指offer 38) 1、字符串的排列(剑指offer 38) 题目描述: 输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。 输入描述: 输入一个字符串,长度不超过9(可能有字符重复),字符只包括大小写字母。 解题思路: 字符串全排列问题,可以...

qq_31467305的博客 361

ai数字人系统部署

这段代码实现了基本的语音交互闭环,用户通过语音输入问题,数字人识别语音后进行自然语言理解并生成回复,再将回复转换为语音输出。但实际应用中的 AI 数字人系统更为复杂,如形象渲染需专业图形引擎(如 Unity、Unreal Engine),自然语言处理也会涉及更复杂的模型微调及多轮对话管理等。一个完整的 AI 数字人系统涵盖形象生成、自然语言处理、动作控制等多个复杂功能,下面为你提供一个 Python 示例,整合多个库来实现数字人基础功能,包括语音交互、简单的自然语言理解以及通过虚拟形象展示对话。

weixin_ggwwsscc的博客 369

【视频监控国标GB/T28181】无人机的视频图传技术

然而,随着无人机市场的不断发展和无人机视频图传技术的迅速进步,一些厂家正积极探索更多的传输方式。如今,一些大疆无人机已经具备了4G辅助图传功能,这意味着它们需要在无人机上安装相应的SIM卡,并在有移动互联网信号的情况下,通过互联网进行视频图传。这种技术的应用,不仅提高了无人机的操作灵活性,也使得无人机在各个领域的应用更加广泛。在使用时,用户需时刻注意无人机的飞行距离。在无人机图传系统中,OFDM技术的运用更是如虎添翼,显著增强了视频传输的品质与稳定性,尤其在错综复杂的电磁环境中,更能凸显其不可替代的优势。

开源物联网项目商业化作者 5661

Leetcode刷题笔记——回溯算法

本文给大家介绍了Leetcode上和回溯算法相关的题型,回溯是递归的副产品,只要有递归就会有回溯,所以回溯法经常和二叉树遍历,深度优先搜索混在一起,因为这两种方式都使用了递归回溯法就是暴力搜索,并不是什么高效的算法,最多再剪枝一下本文给大家介绍的回溯算法如下N个数里面按一定规则找出k个数的集合切割问题:一定字符串按一定的规则有几种切割方式子集问题:一个N个数的集合里有多少符合条件的子集N个数按一定的规则全排列,有几种排列方式。

qq_42898642的博客 1469

37、深入解析SCTP与RTP传输协议

本文深入解析了SCTP与RTP两种重要传输协议。SCTP提供可靠的多流数据传输,支持关联管理、选择性确认和错误处理,适用于高可靠性场景;RTP则专注于实时音视频数据的低延迟传输,配合RTCP实现质量监控。文章详细介绍了两种协议的数据结构、工作流程及应用场景,并对比其特性,帮助开发者根据可靠性、实时性和多流需求选择合适的协议。

time3的博客 83

LeetCode刷题小记 八、【回溯算法】

本系列笔记主要作为笔者刷题的题解,所用的语言为Python3,若于您有助,不胜荣幸。

Shen Mu Xin's Blog 1278

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

LeetCode刷题笔记之回溯算法(一)

LeetCode刷题笔记之回溯算法

abtgu的博客 1064

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

Leetcode刷题模板总结-回溯算法

Leetcode刷题模板总结-回溯算法 回溯算法是较为经典的几个算法之一,经典的问题有八皇后等,今天做leetcode发现一道经典的回溯问题,所以总结一下回溯问题的解题模板。此外做题过程中还发现一直困惑的一个点,即每一次回溯的状态都要new一个新的对象开销太大的问题,下面会仔细分析 Leetcode题目为面试题 08.07 题目很简单,就是需要列出几个字母的全排列,和八皇后或者2020年蓝桥杯省赛电子管的那道题相似,都是回溯的题目,所以这里给出回溯JAVA用递归实现的模板 private void tra

qq_41901420的博客 350

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

LeetCode刷题日记之回溯算法(二)

今天是学习回溯算法的第二天,从昨天的学习中我们可以知道回溯算法也有一套逻辑格式,我们对题目进行对应格式的逻辑分析即可,希望博主记录的内容能够对大家有所帮助 ,一起加油吧朋友们!💪💪💪

粥的博客 1332

Leetcode 刷题笔记1 回溯算法part01

回溯算法的入门,回溯算法更像是一种枚举的策略,本题的组合优化过程可以理解。通过pycharm的调试,对回溯有了初步认识。

pinglejun的博客 390

LeetCode刷题——回溯算法

回溯算法是一种经典的算法思想,通常用于解决组合问题、排列问题、子集问题等。它的核心思想是通过递归和回溯的方式穷举所有可能的解,并在过程中剪枝以减少不必要的计算。

qq_37280410的博客 403

数据结构与算法——LeetCode刷题笔记(八):回溯

数据结构与算法——LeetCode刷题笔记(八):回溯

weixin_42923076的博客 160

Leetcode刷题 | Day25_回溯算法04

输出: [[4, 6], [4, 7], [4, 6, 7], [4, 6, 7, 7], [6, 7], [6, 7, 7], [7,7], [4,7,7]]输出: [ [1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], [3,2,1] ]输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]数层去重,false就continue!输出: [[1,1,2], [1,2,1], [2,1,1]]输入: [1,2,3]

weixin_52152177的博客 793

LeetCode刷题——回溯算法1

回溯是递归的副产品,只要有递归就会有回溯。回溯的本质是穷举,穷举所有可能,然后选出我们想要的答案。回溯法并不高效,它解决的问题都可以抽象为树形结构。

m0_64482337的博客 294

力扣刷题系列——回溯算法I

回溯算法思想及经典例题(一) 回溯法 可以提前看看公众号文章:https://mp.weixin.qq.com/s/g5uvxi1lyxmWC4LtP0Bdlw(从二叉树遍历到回溯算法,包含例题:二叉树路径和等于给定目标值的路径(力扣113)、集合的所有子集合列表(力扣78)) 1、概念 回溯算法实际上一个类似枚举的搜索尝试过程,主要是在搜索尝试过程中寻找问题的解,当发现已不满足求解条件时,就“回溯”返回,尝试别的路径。 回溯法是一种选优搜索法,按选优条件向前搜索,以达到...

qq_43568704的博客 1573

力扣刷题记录

Leecode

Mr_Liuss的博客 2636

力扣刷题全攻略:从算法基础到面试实战

算法与数据结构是程序员的核心竞争力,其本质是通过合理组织数据实现高效计算。从哈希表实现O(1)查询到动态规划优化重复计算,算法思想能显著提升程序性能。在技术面试场景中,力扣(LeetCode)平台已成为评估候选人算法能力的重要标准,特别是热门100题和动态规划等高频考点。掌握滑动窗口、回溯模板等解题模式,配合五步刷题法,能系统提升问题解决能力。工程实践中,这些算法思想广泛应用于推荐系统、搜索引擎等场景,如LRU缓存算法就结合了哈希表与双向链表的优势。通过刻意练习和工具链辅助,开发者可建立从暴力解法到最优方案

weixin_42553471的博客 328
上一篇: JavaSE学习笔记-黑马程序员JAVA注解
下一篇: leetcode数组刷题总结
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值