
树
文章平均质量分 53
树
山顶夕景
互联网大厂AI算法工程师。实践出真知。
展开
-
【Leetcode653】二叉搜索树中两个节点之和(基础题,dfs+哈希)
基础题,二叉树版本的两数之和,dfs遍历这棵二叉搜索树,比如当前节点数值为val,那么就查哈希表key为k - val的键值对是否存在,如果存在则显然说明存在题目说的两个节点,如果不存在不能直接说明没这样的节点(因为可能这对节点才刚出现一个),而是存入该哈希表后继续遍历二叉树。实现中可以用集合set代替哈希表HashMap,速度会快一丢丢。原创 2022-09-17 17:35:14 · 678 阅读 · 0 评论 -
【LeetCode513】找树左下角的值(dfs)
一、题目二、思路dfs遍历二叉树,其实可以直接用前序遍历,注意为了找到最早出现的最深的左节点,所以需要先遍历左子树,再遍历右子树。为了满足“最深”的条件,需要比较当前depth和maxdepth值,进行更新maxdepth。其实题目要求找到最底层的最左边的节点,没指定一定是左孩子哈哈,如果没有左孩子,只有右孩子,那该右孩子也是最左边的节点。三、代码/** * Definition for a binary tree node. * struct TreeNode { * i原创 2022-04-15 12:33:24 · 867 阅读 · 0 评论 -
【LeetCode剑指offer】二叉搜索树的最近公共祖先(迭代or递归)
文章目录一、题目二、思路方法一:迭代法方法二:递归一、题目二、思路求两个节点的最近公共祖先的题目我们做过,但是这题是二叉搜索树BST,并且本题中所有节点的数值都是不同的,所以可以根据BST的数值特点进行判断,即左子树的所有节点都比当前节点小,右子树的所有节点都比当前节点数值大。若 root 是 p,q 的 最近公共祖先 ,则只可能为以下情况之一:p 和 q 在 root 的子树中,且分列 root 的 异侧(即分别在左、右子树中);p = root,且 q 在 root 的左或右子树中;原创 2022-04-05 15:20:52 · 969 阅读 · 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 评论 -
【LeetCode677】键值映射
一、题目提示:1 <= key.length, prefix.length <= 50key 和 prefix 仅由小写英文字母组成1 <= val <= 1000最多调用 50 次 insert 和 sum二、 方法一:暴力扫描方法一:暴力扫描。对哈希表进行增删查改,就是注意找到prefix开头的键key的操作就行。三、代码class MapSum {private: unordered_map<string, int>mp;pub原创 2022-01-28 14:05:17 · 1001 阅读 · 0 评论 -
【LeetCode451】根据字符出现频率排序(优先队列)
一、题目二、思路根据词频排序,很容易想到用哈希表统计每个字符的个数,然后排序。对于“求前k个”或“排序”的题目可以使用堆排序,用优先级队列实现最大堆,进行堆排序,堆顶即当前的最大值。因为我们的pair<char, int>的second才是对应字符(first)的词频,需要的是对second进行排序,所以重写cmp。PS:其实vector就能够排序了,不用priority_queue也是可以的。【C++中STL的优先级队列】在C++的stl中有priority_queue优先级队列原创 2022-01-23 20:53:01 · 1125 阅读 · 0 评论 -
【LeetCode538】把二叉搜索树转换为累加树(BST中序)
1.题目2.思路一定注意有BST的条件,BST的特性是中序遍历(左中右)得到从小到大的序列,而题目求的是大于等于当前结点的值替换原值——注意这里是大于等于!!所以就不是单纯的中序,而是逆中序(右中左)。换句话说从题目的例子我们也能感性观察到左下方一坨的新值是比较大的,而右下方的新值是比较小的,而且我们的逆中序遍历,在逆中序遍历中,我们的全局遍历total在累加的过程依次赋值给当前的结点值,这个赋值过程也是从右下方到开始,再到左边迁移。3.代码# Definition for a binary原创 2021-06-05 00:57:23 · 702 阅读 · 0 评论 -
【LeetCode208】实现Trie(前缀树)
1.题目2.思路这里的前缀树,即“二十六叉树”,但是对于每个结点(对象),我们可以隐性存储一个字符——每个结点(对象)含有一个size为26的指针数组。接着就从根结点开始遍历判断。注意:(1)this指针是指向当前对象的指针,又本题中调用这几个函数的使用对象均是根结点,所以下面的this指针指向根结点自己。(2)C++中考虑防止内存泄漏,需要加上析构函数。3.代码class Trie {private: bool isEnd;//记录该结点是否是一个串的结束 Trie*原创 2021-04-25 17:47:29 · 653 阅读 · 0 评论 -
【LeetCode78】子集(2种回溯法-多叉树的打星号)
文章目录1.题目2.法一:二叉树时间复杂度3.法二:多叉树(打星号)reference1.题目DFS 是一个劲的往某一个方向搜索,而回溯算法建立在 DFS 基础之上的,但不同的是在搜索过程中,达到结束条件后,恢复状态,回溯上一层,再次搜索。因此回溯算法与 DFS 的区别就是有无状态重置.当问题需要 “回头”,以此来查找出所有的解的时候,使用回溯算法。PS:怎么样写回溯算法①画出递归树,找到状态变量(回溯函数的参数),这一步非常重要※②根据题意,确立结束条件③找准选择列表(与函数参数相关)原创 2021-04-09 01:27:30 · 944 阅读 · 0 评论 -
【LeetCode124】二叉树中的最大路径和
1.题目2.思路明确题目的路径定义后,知道有4种路径:(1)单一结点(2)某个结点及其左子树组成的路径(3)某个结点及其右子树组成的路径(4)某个各节点及其左右子树组成的路径(该路径无法作为子路径返回给上一级结点——否则形成的就不是路径了)递归后序遍历,遍历到某个结点时,先获得该结点左右子树中的最大路径,然后将左右子树的最大路径与该结点连接形成以上四种类型的路径,而其实第1、2、3种路径都是(4)的特例。更新全局的最大路径和,然后将max((4)型路径中最大的路径和,res)返回给上一级原创 2021-04-05 20:46:49 · 772 阅读 · 0 评论 -
【LeetCode543】二叉树的直径(还是深度)
1.题目2.思路(1)求二叉树的直径,将问题拆解为求每个结点的左子树高度和右子树高度相加l+r,求所有结点对应的l+r的最大值。(2)关于二叉树的深度之前做过 【LeetCode111】二叉树的最小深度,在之前这题基础上,加多了一个判断。——因为如果出现下图的二叉树时:并按照111题的做法统计出根结点1的左子树和右子树的深度相加,即为3+0=3(非正确答案),而正确答案为4(叶结点之间的最长距离为4,即6-4-2-5-3)。(3)所以需要维护一个maxn,遍历每个结点时,若当前结点的l+r比原创 2021-03-03 11:10:14 · 699 阅读 · 0 评论 -
【LeetCode100】相同的树
一.题目:相同的树给定两个二叉树,编写一个函数来检验它们是否相同。如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的输入: 1 1 / \ / \ 2 3 2 3 [1,2,3], [1,2,3]输出: true输入: 1 ...原创 2020-02-19 03:12:18 · 533 阅读 · 0 评论 -
【LeetCode101】对称二叉树
一.题目:对称二叉树2.算法思想(1)(递归)对称的条件:1.根结点相同 2. 1树的左子树同2树的右子树,1树的右子树同2树的左子树。所以可以用递归实现,注意结构体指针引用元素要用->而不能用小点(2)(迭代)用队列迭代,当队列中每两个连续的结点都是相同值时则互为镜像。该队列的处理:每次提取子树左结点A和右结点B和然后比较,然后将A结点的左结点和B结点的右结点插...原创 2020-02-18 22:17:43 · 598 阅读 · 0 评论 -
【2016-3】字符串的哈夫曼编码长度
1.题目给定一个字符串(长度不超过100),求哈夫曼编码的最短长度样例输入:输入1:abbcccdddd输出1:19输入2:we will we will r u输出2:502.思路好像是第三次做这类似的题了。。用哈夫曼树统计带权路径长度WPL。和【哈夫曼树】合并果子(priority_queue)类似。只不过这题一开始需要利用map进行统计每个字符的个数,再利用priority_queue模拟堆排序,每次将小顶堆的前两个最小值进行累加后,将累加的值temp存入队列中,依次累加t原创 2021-02-20 10:46:23 · 2357 阅读 · 0 评论 -
【2019】二叉树形态总数(卡特兰数)
1.题目题目描述:给定二叉树的节点总数 n,输出二叉树形态总数,n<= 1000输入:3输出:52.思路n个结点组成的二叉树形态总数=卡特兰数=Cmn/(n+1)C_m^n/(n+1)Cmn/(n+1),其中m=2n。可以写一个Cmn函数将分子一块计算出来,最后除以n+1即可。由于n=1000时,计算C会比较大,所以不能使用int型,而要使用long long型。可以回顾一下【LeetCode96】不同的二叉搜索树(dp)则是给出以1、2、…、n为结点组成的二叉搜索树种数,即结点原创 2021-02-18 11:03:12 · 3734 阅读 · 2 评论 -
【LeetCode347】前K个高频元素(pair)
1.题目2.思路(1)方法和【LeetCode215】数组中的第k个最大元素(小顶堆—priority_queue)相同(利用小顶堆,不断加入且保持优先队列恰好为k个元素)。不过注意是将每个元素出现次数加入小顶堆中——所以一开始用unordered_map统计每个元素的出现次数,而因为哈希表的key(即元素)也需要保存,所以优先队列priority_queue里的元素不是int型了:可以用pair<int,int>。(2)在优先队列的排序参数需要重写(因为若直接用greater则是先对p原创 2021-02-15 23:44:23 · 828 阅读 · 2 评论 -
【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 评论 -
【LeetCode215】数组中的第k个最大元素(小顶堆—priority_queue)
1.题目2.思路上个月学过这个思路——10G数中找到前5G大的数。找到前k大,建立一个元素个数为k的小顶堆——这样小顶堆的堆顶在整个堆里就是“前K大”,而将数组剩下的元素依次和堆顶比较,如果大于则替换(相当于不断注入大元素到这个堆集合里,再自动堆重排序),最后的堆顶即整个数组的前k大。3.代码class Solution {public: int findKthLargest(vector<int>& nums, int k) { priority_原创 2021-02-09 23:54:58 · 1163 阅读 · 0 评论 -
【LeetCode98】验证二叉搜索树(medium)
1.题目2.思路二叉排序树的定义中注意不是左孩子小于当前结点,而是左子树上的所有结点值都小于当前结点,因此在递归遍历二叉树的同时需要保存结点权值的上界和下界——实现比较时不止比较子结点的值,也要与上下界比较。递归左孩子时:将当前结点的值作为上界,下界不变;递归右孩子时:将当前结点的值作为下界,上界不变——这里也可以想象一下,根结点的左孩子的右孩子结点的上界仍旧是根结点,而非根结点的左孩子,如下图的叶结点4的上界是根结点5,而非4的父节点2。PS:宏LONG_MAX和LLONG_MAX均存在与头文原创 2021-02-05 20:53:11 · 711 阅读 · 2 评论 -
【LeetCode102】逐层输出二叉树(层次遍历)
1.题目2.思路层次遍历:借助队列,先将根结点入队,然后循环出队首结点,并且将该结点的左子树和右子树加入队列中。(1)题目要求输出每层的结点,而常规模板中的队列是各层结点混在一起的,所以为了区分每层,在原本模板的while里面加了个for循环——该for循环即将一层的结点存入layer数组中,之所以for的遍历次数即改层的结点个数width确定,是因为在进入for前的队列长度即为该层的结点个数。(2)队列中存放的是node*型,而非node型——否则当需要修改队首元素时,就无法对原元素进行修改(只原创 2021-02-01 20:16:40 · 2621 阅读 · 0 评论 -
【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 评论 -
【哈夫曼树】合并果子(priority_queue)
1.题目大概:合并一堆质量不同的果子,使得树的带权路径长度WPL最小。输入包括两行,第一行是一个整数n(1 <= n <= 300000),表示果子的种类数。第二行包含n个整数,用空格分隔,第i个整数ai(1 <= ai <= 100000)是第i种果子的数目。31 2 9输出包括一行,这一行只包含一个整数,也就是最小的体力耗费值。输入数据保证这个值小于263。152.思路哈夫曼树的构建思想:反复选择2个最小的元素,合并,直到只剩下一个元素。一般可使用优先队列(原创 2021-01-19 00:37:17 · 1260 阅读 · 0 评论 -
【1053】Path of Equal Weight (闲置队列)
1.题目https://pintia.cn/problem-sets/994805342720868352/problems/994805424153280512求所有从根结点到叶子结点的路径,使得每条路径上结点的权值之和等于常数S。如果存在多条这样的路径,则按照路径非递增顺序输出。2.思路(1)由于最后的输出要按权值从大到小排序,所以在读入时就事先对每个结点的子结点child进行排序,这样在遍历时就会优先遍历到权值大的子结点。(2)递归过程中保存路径:使用path[]数组表示路径 或者 使用v原创 2021-01-18 15:04:21 · 805 阅读 · 0 评论 -
【1094】The Largest Generation (树DFS-水题)
1.题目https://pintia.cn/problem-sets/994805342720868352/problems/994805372601090048输入树的结点个数N(结点编号为1~N),非叶子结点个数M,然后输入M个非叶子结点各自的孩子结点编号,求结点个数最多的一层(层号是从整体来看的,根结点层号为1),输出该层的结点个数和层号(从根结点的第一层开始往下计算)。2.思路基础题。这类题也是直接DFS,由于不是像上次的【1079】&【1090】供应树DFS一样是到了叶子结点就进原创 2021-01-17 23:40:38 · 729 阅读 · 1 评论 -
【1079】&【1090】供应树DFS
1.题目https://pintia.cn/problem-sets/994805342720868352/problems/994805388447170560给出一棵树,求出叶子结点“带权路径”之和,这里不是以前那种带权,叶子结点真正的权值由该结点的深度决定(幂次方)。看懂题目的输入,每行开头为当前结点i的叶子结点个数,若该首数字非0,则该行后面的数字都为i结点的叶子结点数组下标(也就是题目直接给出结点的编号,且结点的编号一定是0、1、…N-1,N为结点个数——不需要newNode函数,因为题目中原创 2021-01-17 15:14:05 · 686 阅读 · 0 评论 -
树-专题模板
1.基础概念一、几个性质(1)森林是若干树的集合。(2)树可以没有结点(称为空树)。(3)树的层次(深度)是从根节点(从上往下增大)算的;而树的高度是从底层叶子结点(从下往上增大)算的。(4)递归边界:地址root为空,即root==NULL(而非*root==NULL),表示这个结点不存在,而括号是指结点存在但内容为NULL(没有内容)。(5)完全二叉树性质1.当根结点编号为1时,则编号为x的结点的左孩子的编号为2x,右孩子为2x+1。2.数组大小设为结点上限个数+1。3.判断某结点是否原创 2021-01-16 15:43:52 · 851 阅读 · 0 评论 -
二叉树层次遍历
/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; *//*二...原创 2019-07-19 15:24:56 · 653 阅读 · 0 评论 -
二叉树非递归后序遍历
/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; *//*后...原创 2019-07-19 10:58:43 · 8140 阅读 · 0 评论 -
二叉树前序非递归遍历
/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; *//*前...原创 2019-07-19 09:14:53 · 2366 阅读 · 0 评论