递归/回溯

力扣刷题——递归/回溯+dfs/bfs 又到了星期五了,又能愉快的刷题了,嗯,真不错。真好,本菜鸟今天晚上花了一个半小时,终于写出来了三道题,两道关于递归/回溯,一道是关于dfs/bfs。发现dfs/bfs真是写的越来越顺手了,可能是刷多了的缘故吧(虽然这方面的题只刷了十来道)。 通过今天的刷题发现自己还是对回溯算法不太熟悉,还有8天就蓝桥杯国赛了,在此之前,一定要好好学一学回溯算法... 阅读详情

一、没有重复项数字的全排列

给出一组数字,返回该组数字的所有排列

例如:

[1,2,3]的所有排列如下
[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2], [3,2,1].
(以数字在数组中的位置靠前为优先级,按字典序排列输出。)

数据范围:数字个数 0<n≤6

要求:空间复杂度 O(n!),时间复杂度 O(n!)

import java.util.*;

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     *
     * @param num int整型一维数组
     * @return int整型ArrayList<ArrayList<>>
     */
    public ArrayList<ArrayList<Integer>> permute (int[] num) {
        // write code here
        ArrayList<ArrayList<Integer>> res = new ArrayList<>();
        dfs(num, res, new ArrayList<>(), 0);
        return res;

    }
    void dfs(int[] num, ArrayList<ArrayList<Integer>> res, ArrayList<Integer> t,
             int index) {
        if (t.size() == num.length) {
            res.add(new ArrayList<>(t));
            return;
        }
        for (int i = 0; i < num.length; i++) {
            if (t.contains(num[i])) {
                continue;
            }
            t.add(num[i]);
            dfs(num, res, t, i + 1);
            t.remove(t.size() - 1);
        }
    }
}

运行结果

二、有重复项数字的全排列

给出一组可能包含重复项的数字,返回该组数字的所有排列。结果以字典序升序排列。

数据范围: 0<n≤8 ,数组中的值满足 −1≤val≤5

要求:空间复杂度 O(n!),时间复杂度 O(n!)

import java.util.*;

public class Solution {

    ArrayList<ArrayList<Integer>> list = new
    ArrayList<>(); // 存最终全排列结果
    ArrayList<Integer> tmp = new ArrayList<>(); // 当前排列结果
    Set<Integer> set = new
    HashSet<>(); // 存已用数组元素的下标,防重复

    public ArrayList<ArrayList<Integer>> permuteUnique (int[] num) {
        Arrays.sort(num); // 升序
        dfs(num);  // 调用 dfs
        return list;
    }

    // dfs
    public void dfs(int[] nums) {
        if (tmp.size() == nums.length) {
            ArrayList<Integer> t = new ArrayList<>(tmp);
            if (!list.contains(t)) list.add(
                    t); // 由于元素可能重复,导致排列可能重复,要判断一下
            return;
        }

        for (int i = 0; i < nums.length; i++) {
            if (set.contains(i)) continue; // 下标重复
            tmp.add(nums[i]);
            set.add(i);
            dfs(nums); // 排列数组下个元素
            tmp.remove(tmp.size() - 1); // 回溯
            set.remove(i);
        }
    }
}

运行结果

三、岛屿数量

给一个01矩阵,1代表是陆地,0代表海洋, 如果两个1相邻,那么这两个1属于同一个岛。我们只考虑上下左右为相邻。

岛屿: 相邻陆地可以组成一个岛屿(相邻:上下左右) 判断岛屿个数。

例如:

输入

[

[1,1,0,0,0],

[0,1,0,1,1],

[0,0,0,1,1],

[0,0,0,0,0],

[0,0,1,1,1]

]

对应的输出为3

(注:存储的01数据其实是字符'0','1')

import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 判断岛屿数量
     * @param grid char字符型二维数组
     * @return int整型
     */

    public int solve (char[][] grid) {
        //递归找
        int x = grid.length;
        int y = grid[0].length;
        int res = 0;
        int [][] moveGrid = new int[4][2];  //右下左上
        moveGrid[0] = new int[] {0, 1};
        moveGrid[1] = new int[] {1, 0};
        moveGrid[2] = new int[] {0, -1};
        moveGrid[3] = new int[] {-1, 0};
        for (int i = 0; i < x; i++) {
            for (int j = 0; j < y; j++) {
                char element = grid[i][j];
                if (element == '1') {
                    recircleSearch(grid, i, j, moveGrid);
                    res++;
                }
            }
        }
        return res;
    }

    public void recircleSearch(char[][] grid, int i, int j, int[][]moveGrid) {
        if (i < 0 || i >= grid.length || j < 0 || j >= grid[0].length) return;
        if (grid[i][j] == '0' || grid[i][j] == 'x') return ;
        grid[i][j] = 'x';
        for (int k = 0; k < 4; k++) {
            recircleSearch(grid, i + moveGrid[k][0], j + moveGrid[k][1], moveGrid);
        }
    }

}

运行结果

四、字符串的排列

输入一个长度为 n 字符串,打印出该字符串中字符的所有排列,你可以以任意顺序返回这个字符串数组。

例如输入字符串ABC,则输出由字符A,B,C所能排列出来的所有字符串ABC,ACB,BAC,BCA,CBA和CAB。

import java.util.*;

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     *
     * @param str string字符串
     * @return string字符串ArrayList
     */
    public ArrayList<String> Permutation (String str) {
        ArrayList<String> res = new ArrayList<>();
        char[] chars = str.toCharArray();
        Arrays.sort(chars);
        boolean[] visited = new   boolean[chars.length];
        dfs(chars, res, new StringBuilder(),  visited);
        return res;
    }
    void dfs(char[] chars, ArrayList<String> res, StringBuilder tmp,
             boolean[] visited) {
        if (chars.length == tmp.length()) {
            res.add(new String(tmp));
            return;
        }

        for (int i = 0; i < chars.length; i++) {
            if (visited[i]) {
                continue;
            }
            if (i > 0 && chars[i] == chars[i - 1] && !visited[i - 1]) {
                continue;
            }
            tmp.append(chars[i]);
            visited[i] = true;
            dfs(chars, res, tmp,  visited);
            visited[i] = false;
            tmp.deleteCharAt(tmp.length() - 1);
        }
    }
}

运行结果

五、N皇后问题

N 皇后问题是指在 n * n 的棋盘上要摆 n 个皇后,
要求:任何两个皇后不同行,不同列也不在同一条斜线上,
求给一个整数 n ,返回 n 皇后的摆法数。

数据范围: 1≤n≤9

要求:空间复杂度 O(n) ,时间复杂度 O(n!)

import java.util.*;


public class Solution {

    int ans = 0;
    //分别对应竖向标记,左下角标记,右下角标记,数组长度跟据n的最大范围囊括一下即可
    boolean[] b = new boolean[100]; //y
    boolean[] c = new boolean[100]; //x + y - 1
    boolean[] d = new boolean[100]; //x - y + n

    public int Nqueen (int n) {
        //一定要从1开始,否则会出现数组越界(如-1)
        dfs(1, n);
        return ans;
    }

    public void dfs(int x, int n) {
        if (x > n) {
            ans++;
            return;
        }
        for (int y = 1; y <= n; y++) {
            if (!b[y] && !c[x + y - 1] && !d[x - y + n]) {
                b[y] = true;
                c[x + y - 1] = true;
                d[x - y + n] = true;
                dfs(x + 1, n);
                b[y] = false;
                c[x + y - 1] = false;
                d[x - y + n] = false;
            }
        }
    }
}

运行结果

六、括号生成

给出n对括号,请编写一个函数来生成所有的由n对括号组成的合法组合。

例如,给出n=3,解集为:

"((()))", "(()())", "(())()", "()()()", "()(())"

import java.util.*;


public class Solution {
    public ArrayList<String> generateParenthesis(int n) {
        ArrayList<String> res = new ArrayList<>();
        dfs(res, new char[n * 2], 0, 0);
        return res;
    }

    private void dfs(List<String> res, char[] arr, int l, int r) {
        int n = arr.length, idx = l + r;
        if (idx == n) {
            res.add(new String(arr));
        }
        if (l < n / 2) {
            arr[idx] = '(';
            dfs(res, arr, l + 1, r);
        }
        if (l != r) {
            arr[idx] = ')';
            dfs(res, arr, l, r + 1);
        }
    }
}

运行结果

七、矩阵最长递增路径

给定一个 n 行 m 列矩阵 matrix ,矩阵内所有数均为非负整数。 你需要在矩阵中找到一条最长路径,使这条路径上的元素是递增的。并输出这条最长路径的长度。

这个路径必须满足以下条件:

1. 对于每个单元格,你可以往上,下,左,右四个方向移动。 你不能在对角线方向上移动或移动到边界外。

2. 你不能走重复的单元格。即每个格子最多只能走一次。

数据范围:1≤n,m≤1000,0≤matrix[i][j]≤1000

进阶:空间复杂度 O(nm) ,时间复杂度 O(nm)

import java.util.*;


public class Solution {
    public int solve(int[][] matrix) {
        int res = 0, m = matrix.length, n = matrix[0].length;
        int[][] dp = new int[m][n];
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                res = Math.max(res, dfs(dp, matrix, i, j, -1));
            }
        }
        return res;
    }

    private int dfs(int[][] dp, int[][] grid, int i, int j, int min) {
        if (i < 0 || i >= grid.length || j < 0 || j >= grid[0].length ||
                grid[i][j] <= min) {
            return 0;
        }
        if (dp[i][j] == 0) {
            int res = 1;
            res = Math.max(res, dfs(dp, grid, i - 1, j, grid[i][j]) + 1);
            res = Math.max(res, dfs(dp, grid, i + 1, j, grid[i][j]) + 1);
            res = Math.max(res, dfs(dp, grid, i, j - 1, grid[i][j]) + 1);
            res = Math.max(res, dfs(dp, grid, i, j + 1, grid[i][j]) + 1);
            dp[i][j] = res;
        }
        return dp[i][j];
    }
}

运行结果

回溯算法求解数独问题(C++ 递归/非递归) 如何使用求解上述数独? 递归实现 #include<bits/stdc++.h> using namespace std; int sudoku[9][9]; int dx[9]= {-1,-1,-1,0,0,0,1,1,1},dy[9]={-1,0,1,-1,0,1,-1,0,1}; void print(){ for(int i=0;i<9;i++){ for... 阅读详情

相关推荐

基于FastLIO2与TEB算法的机器狗自主导航系统实战

本文详细介绍了如何为机器狗构建一套基于FastLIO2与TEB算法的自主导航系统。通过整合FastLIO2激光惯性里程计实现精准定位,并采用TEB局部规划器进行灵活路径规划与动态避障,解决了传统方案在复杂地形下反应慢、易碰撞的问题。文章提供了从环境搭建、算法部署、地图转换到系统调试的完整实战指南,帮助开发者实现机器狗的稳健自主行走。

beer8的博客 321

力扣hot100-->递归/回溯

/ 定义一个字符串向量 v,存储数字到字母的映射关系,数字 2 到 9 分别对应不同的字母组合。// 递归结束条件:当 path 的长度等于输入的数字串长度时,将当前组合添加到结果中。// 回溯:移除最后一个添加的字母,以便尝试下一个字母组合。// 定义一个字符串向量 result,用于存储所有可能的字母组合结果。// 递归函数 recursive,用于生成所有可能的字母组合。// 定义一个字符串 path,用于记录当前组合的路径。// 根据当前数字获取对应的字母字符串。// 返回所有生成的字母组合。

Dong雨的博客 544

Innovus ECO技巧:用setEcoMode+ecoAddRepeater实现批量buffer替换的5个关键步骤

本文详细介绍了在Cadence Innovus工具中,利用setEcoMode与ecoAddRepeater命令实现高效、批量Buffer/Inverter替换的工程化策略。通过启用批处理模式、构建可维护的替换规则、掌握高级定位技巧以及规避布线陷阱等5个关键步骤,帮助芯片设计工程师在ECO阶段大幅提升修改效率与质量,确保设计稳定签核。

d6e7f8的博客 1119

递归回溯生成和解决数独问题c/c++

递归回溯生成和解决数独问题c/c++

wangchaoqi1985的博客 111

关于Arduino中的常用函数

一、I/O函数 二、时间函数 三、数学函数 abs 返回其参数的无符号值 【abs(12)返回12,abs(-12)也返回12】 constrain 限制一个数字以阻止它超出范围。第一个参数是被限制的数字,第二个参数是范围区间的开始,第三个参数是允许的数字范围区间的结尾。 【constrain(8,1,10)返回8,constrain(11,1,10)返回10,constrain(0,1,10)返回1】 map 将一个范围内的数字映射到另一个范围。第一个参数是要映射到数字,第二个和第三个参数是from范围(

TREE的博客 7323

深入解析Lora模块的工作原理与应用场景

本文深入解析了Lora模块的工作原理与应用场景。Lora模块作为物联网领域的核心无线通信组件,凭借其独特的扩频调制与半双工通信技术,实现了远距离、低功耗的数据传输。文章详细拆解了其技术内核,包括空中唤醒等低功耗奥秘,并提供了地址、信道、空中速率等关键参数的实战配置指南。最后,探讨了Lora模块在智能家居、智慧农业、城市监测等广域物联网场景中的具体应用,为开发者提供了从理论到实践的完整参考。

weixin_29174385的博客 333

leetcode【递归/回溯问题】总结

回溯问题分析 注意: 整体思路清晰,回溯的过程大概是怎样的 每层递归实际上要解决的问题是什么 一定记住,该重置的状态要重置,因为回溯就是相当于在每一层的递归中做选择,选择了不同的选项,在遇到阻碍或者达到条件结束递归之后,再想尝试其他的选择路径,应当记住回退到之前的状态。 纵向:递归的深度,完整地解决问题(搜索完所有的方案/找到最优方案 )所必须完成地一整个连续过程,该过程的长度。例如,在“选/不选”递归(0/1递归)中,递归的深度是可选值的数量。 对于纵向思维,要有层层深入,逐渐解决问题的概念。对

ftfy123的博客 537

ComfyUI-controlnet控制出图

提供加载预处理器节点。

Bu2n的博客 5494

树与DFS/BFS/回溯/递归的思维整合方法论

树是一种天然递归定义的数据结构,其遍历与搜索问题本质上统一于递归范式;DFS体现深度优先的状态延续性,BFS保障层序扩展的最短解性质,回溯则是DFS在路径约束下的状态维护与撤销机制;四者并非孤立算法,而是围绕树形结构展开的协同思维工具。掌握其内在耦合关系,可显著提升算法设计效率与工程落地稳定性,广泛适用于路径搜索、组合生成、拓扑分析及分布式任务调度等真实场景。

weixin_33552698的博客 259

Carla-UE4Editor导入RoadRunner地图文件(保姆级教程)

以Carla官网导入RoadRunner地图的标准文档为参考,里面增添了很多细节和注意事项,遇到问题的小伙伴过来看看吧。

DSK_981029的博客 1万+

静态编译Qt5源码(Kylin-Desktop-V10-SP1-2203-LoongArch64+qt5.15.16)

之前的文档,记录的是通用情况,本次笔者记录下Qt5的静态编译过程,供有需要的小伙伴参考使用的操作系统是Kylin-Desktop-V10-SP1-General-Release-2203-LoongArch64,处理器是龙芯3A5000,架构是loongarch。

aggs1990的专栏 1402

【递归/回溯】实现手段

不用一层层深入下去看,而是把后面的部分理解成“已经递归完的结果”。比如说二叉树的题,就把问题看成根节点,左子树递归完的结果和右子树递归完的结果。不要再深入左子树、右子树了。递归中有循环的话,图是这样画的,有几个循环就有几个结点(参考八皇后问题、迷宫问题)

qq_44886213的博客 285

锂电池SOC估计 | 基于LSTM长短期记忆神经网络的锂电池SOC估计(附matlab完整代码)

锂电池SOC估计 | 基于LSTM长短期记忆神经网络的锂电池SOC估计(附matlab完整代码)

前程算法屋的博客 1023

算法基础/递归回溯

当要求解全排列或者全部的组合时,常采用递归+回溯的方式。 标准的递归+回溯: DFS形式DFS(nums,index)//表示当前位置是index, 1)对于每个位置的数,要么被选中,temp.push_back(nums[index],DFS(nums,index+1),回溯的时候,从temp中删除,temp.pop_back(). 2)要么不被选中,直接递归下一个元素DFS(nums,index+1). 3)当当前位置到达num.size()时,将temp数组压入结果中,结束递归。 1.

chihiro的博客 576

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

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

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

算法:[递归/搜索/回溯]综合练习题

本篇博客是关于 dfs 穷举/暴搜/深搜/回溯/剪枝 的综合练习题,每道题都超链接了力扣的网页,每道题都有详细的解答过程

一名还在努力学习技术的程序员的博客 747

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

算法:[递归/搜索/回溯]递归

本篇博客是关于 [递归/搜索/回溯]系列之递归的练习题,每道题都超链接了力扣的网页,每道题都有详细的解答过程

一名还在努力学习技术的程序员的博客 720

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

leetcode回溯/递归java

回溯 递归 n叉树 组合 切割 子集 排列 棋盘 N皇后,解数独等等

csf94的博客 344

leetcode刷题:递归 / 回溯

系列文章目录 leetcode刷题:第一周 leetcode刷题:第二周 leetcode刷题:二分查找 leetcode刷题:双指针 leetcode刷题:广度/深度优先搜索 leetcode刷题:递归 / 回溯 文章目录系列文章目录前言递归/回溯1.子集2.子集 II3.全排列 II4.组合总和5.组合总和 II6.电话号码的字母组合7.括号生成8.单词搜索总结 前言 这次博客记录一些leetcode有关递归和回溯的题目 递归/回溯 1.子集 给你一个整数数组 nums ,数组中的元素 互不相同

weixin_50835854的博客 930

回溯法经典实战:0/1 全排列与 N 皇后问题(递归 + 非递归双实现)

回溯法本质是试探 + 回退按路径尝试所有可能解;发现当前路径不合法 / 无解时,回退到上一步重新选择;直到找到所有合法解。基础案例:生成 n 位 0/1 全排列经典案例:N 皇后问题(算法必考题)试探→验证→回溯→再试探;0/1 全排列是回溯法入门模板,掌握选 / 不选逻辑;N 皇后是回溯法经典应用,重点理解位置合法性判断;递归适合写算法题,非递归适合实际工程使用。

W2303576573的博客 194

回溯/递归——八皇后

问题描述:在8X8的棋盘上放置八个皇后,任意两个皇后都不能处于同一行、列或者同一斜线上。 分析:每行只能放一个,每列只能放一个。 如何判段在当前位置是否可以防止皇后 行和列的判断很简单,主要是对角线的判断 在 / 对角线上的点:行 + 列相等 在 \ 对角线上的点:行 - 列相等 通过建立皇后对象的结构体,重载==实现两个皇后相等的判断 bool operator==(const Queen&a...

不积极分子 246

回溯与递归 3/24

昨天学习递归跟回溯,感觉还是有些吃力 /** 求一个序列的所有子集,序列中元素无重复,可以使用二进制思想,也可以使用回溯跟递归,放该元素,与不放该元素 */ /*回溯思想/ std::vector<std::vector<int> > getSubSet(std::vector<int> &nums) { std::vector<std::v...

kangjianflying的博客 157

递归/回溯中「状态传递」

基本类型参数只往下传,要累计就上成员变量或包装数组;引用类型参数天然共享,改了要恢复;自底向上汇总用返回值。回溯题优先“参数传剩余量 + 成员变量收集结果”,少用“基本类型成员变量 + 手动恢复”,能少一半 bug。

2501_94245083的博客 225

草稿【递归/回溯 ≈ 树结构递归】【递归 = 分解 || 遍历】

说明这个函数参数的含义是什么,返回什么结果。这样你才能利用这个定义来计算子问题,反推原问题的解。斐波那契数列的递归函数 fib 就有一个清晰的定义,且算法就在利用这个定义:// 定义:输入一个非负整数 n,返回斐波那契数列中的第 n 个数return n;// 利用定义,计算前两个斐波那契数(子问题)

weixin_47868976的博客 859

二叉树/递归/回溯/动规的框架思维

而前序位置本身其实没有什么特别的性质,之所以很多题都是在前序位置写代码,实际上是因为我们习惯把那些对前中后序位置不敏感的代码写在前序位置罢了。,每个节点都有唯一的前中后序位置,在递归的过程中,需要在进入/离开/切换节点的时候执行核心代码,就把核心代码放到对应的前中后序位置!如果采用遍历,也就是回溯的方法,其思路是遍历一遍二叉树,用一个外部变量记录每个节点所在的深度,取最大值就可以得到最大深度。如果采用分解,也就是动规的方法,其思路就是二叉树的最大深度=max(左子树的最大深度,右子树的最大深度)+1。

weixin_51076267的博客 1446

视频隐私脱敏工程化:CSRT/KCF追踪算法在本地推理中的实现与边界

在短视频内容合规审查中,动态遮挡(Dynamic Masking)是高频且高耗时的环节。传统手动关键帧打码不仅效率低下,且在目标快速移动或遮挡时极易出现遮罩漂移。本文从计算机视觉工程角度,解析基于CSRT与KCF算法的目标追踪方案在视频隐私处理中的技术路径、性能权衡及落地实践。

Mysssone的博客 235
上一篇: 哈希/数组
下一篇: 动态规划(一)
w_zero_one
博客等级 码龄2年 149粉丝 68原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值