
递归
文章平均质量分 53
递归
山顶夕景
互联网大厂AI算法工程师。实践出真知。
展开
-
n皇后暴力&回溯法
【问题描述】在一个n*n棋盘上放n个皇后,满足n个皇后两两均不在同一行、同一列、同一条对角线上,求满足条件的方案数。【思路】1.暴力法如果直接想暴力枚举所有情况,从nn个位置中选择n个位置,则需要Cnn n种情况,如n=8时就需要54 502 232种情况,挺大的数字了;但如果想:每行、列均只能放置一个皇后,而现在把n列皇后所在的行号依次写出,相当于一个1~n的全排列,即只有n!种情况。可以回顾之前的文章:递归实现全排列&使用STL现在就在全排列的基础上求解。由于当到达递归边界时表示原创 2021-01-07 22:32:10 · 809 阅读 · 0 评论 -
递归实现全排列&使用next_permutation
递归实现全排列&使用STL1.递归版栗子:对1、2、3三个数字进行全排列,并按照字典序从小到大的顺序进行输出1~n的全排列。【思路】递归角度,如果把问题描述成“输出1~n这n整数的全排列”——将原问题分为若干子问题:“输出以1开头的全排列”、“输出以2开头的全排列”、“输出以3开头的全排列”。。。“输出以n开头的全排列”。【做法】数组P——存放当前的排列;数组hashtable[x]——为true时即整数x已经在数组P中。(1)按顺序将P数组的第1到n位中填入数字,假设填好了P[1]原创 2021-01-07 16:17:02 · 925 阅读 · 0 评论 -
【Leetcode152】分割回文串(回溯 | 递归)
这样,通过递归和回溯的方法,我们可以找到所有可能的分割方案。(这个路径即当前方案的所有字符组合列表),直到字符串。每次递归调用会传递新的字符串。具体例子和步骤:假设。原创 2024-09-18 21:46:38 · 491 阅读 · 0 评论 -
【递归】把不规则列表里面的非字符串元素去掉
递归基础题。递归边界:遇到字符串就将当前元素添加到答案列表;递归函数:遇到列表就将该列表递归,注意是要遍历该列表,对此列表每个元素进行递归!原创 2023-01-06 18:42:32 · 446 阅读 · 0 评论 -
【LeetCode24】两两交换链表中的节点(递归)
文章目录一、题目二、思路三、代码一、题目二、思路可以使用递归方法:递归终止条件:链表中没有节点,或者只剩下一个节点(不能进行交换了)。递归体:首先用head保存原始链表的头节点,newhead保存新链表的头节点(即head->next),则原始链表的其他节点开始是newhead->next。解决递归需要清楚递推公式含义:这里递推公式swapPairs()指将给定的链表中的相邻节点两两交换后返回,返回的是交换完成的链表的头节点。所以假设我们已经将head->next后的节点都原创 2022-04-04 10:31:19 · 1588 阅读 · 0 评论 -
【LeetCode剑指offer12】矩阵中的路径(dfs回溯)
文章目录一、题目二、思路三、代码一、题目二、思路递归参数: 当前字符在矩阵 board 中的行索引 i 和列索引 j ,当前目标字符(匹配的)在目标字符串 word 中的索引 k 。终止条件:返回 false : (1) 行索引或列索引越界 (2) 当前矩阵字符与目标字符不同;返回 true : 当前目标字符(匹配的)在目标字符串 word 中的索引 k = len(word) - 1 ,即目标字符串 word 已全部匹配;递归过程:标记访问过字符: 将 board[i][j] 修改为 ‘/原创 2022-04-03 10:17:26 · 827 阅读 · 0 评论 -
【LeetCode剑指offer34】二叉树中和为某一值的路径(dfs回溯)
文章目录一、题目二、思路三、代码一、题目提示:树中节点总数在范围 [0, 5000] 内-1000 <= Node.val <= 1000-1000 <= targetSum <= 1000二、思路回溯思想,dfs首先将当前的元素加入,然后判断到目前为止的temp数组是否满足sum=target的一种情况,如果不满足则继续递归遍历左子树和右子树。注意!!!当左子树和右子树都为空时,即当前节点为叶子结点了,到底的判断完了!!就把temp数组刚才存的最后一个(叶子)节原创 2022-03-31 13:29:09 · 2183 阅读 · 0 评论 -
【LeetCode剑指offer26】树的子结构(递归)
文章目录一、题目二、思路三、代码一、题目限制:0 <= 节点个数 <= 10000二、思路题目判断的是B是否为A树的【子结构】,而不判断是【子树】。直观的思路:从A的每个节点开始逐个(递归)遍历,(假设当前的节点为K);然后判断B树,是否为当前以K节点为头结点的子结构。上面第二步,对应下面代码的issame部分:如果B树为空(先遍历完了),则是子结构;如果B树不空,A树为空(A树先遍历完了),则不是子结构;AB树当前节点都不空了,但是val不相同,也不是子结构了;原创 2022-03-25 20:31:59 · 844 阅读 · 0 评论 -
【LeetCode剑指offer33】二叉搜索树的后序遍历序列(找分界点)
文章目录一、题目二、思路三、代码一、题目二、思路单纯根据后序遍历序列,不阔能确定一棵二叉树,但是事先说明是二叉搜索树BST了,BST树的特点是中序遍历序列,是有序序列,而且根结点val大于左孩子val,小于右孩子val。而且题目给出后序遍历序列,最后一个节点是根结点,我们就能从头遍历数组,找到第一个比根结点大的节点位置(分界点),在此前面的部分,都是根结点的左子树部分;分界点后面部分理应是右子树部分,所以val也理应该大于根结点。所以基于这点,我们只要判断分界点后的结点值,是否有小于根结点的这种异原创 2022-03-17 11:23:30 · 1368 阅读 · 0 评论 -
【LeetCode173】二叉搜索树迭代器(中序遍历)
一、题目二、思路题目要求BST二叉搜索树的中序遍历迭代器,所以只需要对BST先进行中序遍历,得到这个中序遍历数组,然后对该数组进行next操作和havenext操作即可。在实现过程中,注意引用、构造函数的初始化列表等细节。三、代码/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; *原创 2022-02-22 20:36:03 · 878 阅读 · 0 评论 -
【LeetCode剑指offer38】字符串的排列(回溯+去重or剪枝)
一、题目二、思路【方法一】回溯+set和全排列题目差不多的【回溯】套路,但是多了去重操作,比如aba的两个a视为相同的字符,即不能出现两个aab在结果vector中,最简单的方法就是在回溯模板上添个unordered_set去重后存入vector<string>中即可,但是这样木有剪枝,时间复杂度稍慢点。【方法二】回溯+排序判断(剪枝法)第二种去重方法是通过预处理实现去重:(1)先对原字符串进行排序;(2)然后确保相同字符传入同一目标位置的动作只发生一次。【方法三】C++中ne原创 2022-02-10 15:56:46 · 1314 阅读 · 0 评论 -
【LeetCode114】二叉树展开为链表(递归)
1.题目2.思路不能使用先序遍历(根-左-右),因为顺序应该是 上-下-上 的2个过程(下探和回溯)。递归分解思路: 1 / \ 2 5 / \ \3 4 6----------- root = 4 pre = 5 1 / 2 / \ 3 4 \ 5 \ 6----------- root = 3 pre = 4 1原创 2021-04-17 21:13:44 · 713 阅读 · 0 评论 -
【LeetCode226】翻转二叉树(Howell的噩梦)
1.题目2.思路基础递归题。可以直接后序遍历(前序也可),递归到底后就交换左右孩子(叶结点),再往二叉树上返回。前序和后序唯一的区别是:前序遍历:将「处理当前节点」放到「递归左子树」之前。后序遍历:将「处理当前节点」放到「递归右子树」之后。3.代码/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *righ原创 2021-04-17 14:50:11 · 627 阅读 · 0 评论 -
【LeetCode206】反转链表(迭代or递归)
1.题目2.法一:迭代要将链表翻转,即每个结点的next指针指向前一个结点,也即至少需要2个指针指向这两个结点(slow和fast),但是当fast所指向的结点的next指针调整完毕后就已经“断链”,为了让这两个指针能够继续往后移动一位,所以需要提前保存fast所指向结点的下一个结点。/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; *原创 2021-04-10 16:11:41 · 754 阅读 · 1 评论 -
【LeetCode78】子集(2种回溯法-多叉树的打星号)
文章目录1.题目2.法一:二叉树时间复杂度3.法二:多叉树(打星号)reference1.题目DFS 是一个劲的往某一个方向搜索,而回溯算法建立在 DFS 基础之上的,但不同的是在搜索过程中,达到结束条件后,恢复状态,回溯上一层,再次搜索。因此回溯算法与 DFS 的区别就是有无状态重置.当问题需要 “回头”,以此来查找出所有的解的时候,使用回溯算法。PS:怎么样写回溯算法①画出递归树,找到状态变量(回溯函数的参数),这一步非常重要※②根据题意,确立结束条件③找准选择列表(与函数参数相关)原创 2021-04-09 01:27:30 · 944 阅读 · 0 评论 -
【LeetCode46】全排列(DFS)
1.题目2.思路DFS遍历,回溯。vector<bool>hashtable(nums.size(),false);这句不要漏了,虽然vector型初始化后数值默认为0即false,但这里也要初始化大小,不然会报错。可以回顾n皇后 暴力&回溯这篇,基本一样的题。3.代码class Solution {public: vector<vector<int> >result; vector<int>p;//装入的一组原创 2021-01-27 23:58:47 · 750 阅读 · 0 评论 -
【LeetCode39】组合总和(回溯法)
1.题目2.思路由于要求出所有情况,而非求出可能的情况数,所以不使用动态规划,要用回溯法。(1)由于每个数字可以重复选择,所以递归的即不选择当前数的dfs的参数index不用加1。(2)由于传参的candidates不用传值,而用传值,试了下时间相差了30%。3.代码class Solution {public: vector<vector<int>>ans; //int n=candidates.size(); vector<int&原创 2021-01-30 23:52:47 · 787 阅读 · 0 评论 -
【LeetCode17】电话号码的字母组合(DFS回溯)
1.题目2.思路之前做的【HJ21】简单密码破解(字符转换)也涉及手机按键字符是将字符分为两种:三个字母一组,四个字母一组,再利用ASCII码找规律。为了后面深搜方便遍历,这题我们利用map<char,string>将数字字符和对应的按键字母对应起来。dfs遍历,如输入digits为“23”时,这颗遍历树分别(指向)遍历数字2对应的三个字母a、b、c,该三个分支的每个分支,又指向数字3所对应的3个字母d、e、f。3.代码class Solution {private:原创 2021-02-22 11:33:57 · 764 阅读 · 0 评论 -
【LeetCode98】验证二叉搜索树(medium)
1.题目2.思路二叉排序树的定义中注意不是左孩子小于当前结点,而是左子树上的所有结点值都小于当前结点,因此在递归遍历二叉树的同时需要保存结点权值的上界和下界——实现比较时不止比较子结点的值,也要与上下界比较。递归左孩子时:将当前结点的值作为上界,下界不变;递归右孩子时:将当前结点的值作为下界,上界不变——这里也可以想象一下,根结点的左孩子的右孩子结点的上界仍旧是根结点,而非根结点的左孩子,如下图的叶结点4的上界是根结点5,而非4的父节点2。PS:宏LONG_MAX和LLONG_MAX均存在与头文原创 2021-02-05 20:53:11 · 711 阅读 · 2 评论 -
【LeetCode105和106】先序和中序构造二叉树(106是中后序构树)
1.题目2.思路做过很多次了,由于中序序列是“左中右”遍历顺序,而先序序列是“中左右”遍历序列,所以可以根据先序序列的第一个元素确定当前的根结点,再遍历一次中序序列从中找到根结点所在的下标,从而确定当前中序序列的左子树结点个数numleftnumleftnumleft——int numleft=k-inl这里注意减inl,虽然传参inl为0,一开始没有写inl报错出如下信息:AddressSanitizer: heap-buffer-overflow on address 0x60300000003原创 2021-01-29 09:36:25 · 802 阅读 · 0 评论 -
【LeetCode617】合并二叉树(遍历,返回值)
1.题目2.思路其实用前序、中序、后序遍历都可以,另外递归注意有返回值。C++的new运算符,如int* p=new int;即只需要“new+类型名”即可分配该类型的内存空间,并返回一个对应类型的指针。下面new TreeNode(0)利用结构体的构造函数,返回指向TreeNode型内存的指针,即TreeNode型。3.代码/** * Definition for a binary tree node. * struct TreeNode { * int val; *原创 2021-02-10 01:00:20 · 673 阅读 · 0 评论