树图算法
树算法
爱抖腿的嘻嘻嘻
这个作者很懒,什么都没留下…
展开
-
拓扑排序1.课程表
利用map来构成图,依据题中给的边缘列表构建邻接表,然后再建立入度表,从入度为0的顶点开始排序,如果到最后仍有顶点的入度不为0,则说明它的条件依然没有满足,则无法输出。import java.util.HashMap;import java.util.LinkedList;import java.util.ArrayList;class Solution { public boolean canFinish(int numCourses, int[][] prerequisites) {原创 2021-01-09 01:47:32 · 186 阅读 · 2 评论 -
遍历3寻找重复子树653
寻找一颗二叉树中的重复子树,并且把重复子树加到一个list中,同一个子树只要加1次,所以遍历所有节点,然后将以它为根节点的子树加到map中,如果此时这个节点有一次,则把它加到结果列表中,如果有0次,则加到map中,超过1次就不处理。class Solution { Map<String,Integer> map=new HashMap<String,Integer>(); List<TreeNode> res=new ArrayList<TreeN原创 2021-04-04 14:32:12 · 82 阅读 · 0 评论 -
字符串->树 3.重建二叉树(已知中序后序)106
class Solution { public TreeNode buildTree(int[] inorder, int[] postorder) { return build(inorder,0,inorder.length-1,postorder,0,postorder.length-1); } public TreeNode build(int[] inorder, int lo1,int hi1,int[] postorder,int lo2,int hi2原创 2021-04-04 12:45:58 · 99 阅读 · 0 评论 -
递归6.最大二叉树654
利用递归来一层层的建造class Solution { public TreeNode constructMaximumBinaryTree(int[] nums) { return core(nums,0,nums.length-1); } public TreeNode core(int[] nums,int lo,int hi){ if(lo>hi)return null; int maxIndex=-1;原创 2021-04-04 10:29:25 · 86 阅读 · 0 评论 -
递归5.二叉树展开成为单链表114
将一个二叉树用前序遍历的顺序展开成为一个全是右子树顺序的树。因为主要是到当前节点的时候会使得前一个节点丢失,所以在遍历的时候要保存前一个节点,然后将此时的节点当作上个节点的右节点,左节点为null。因为之前保存了原来的右节点,所以不用担心丢失,等遍历完最后一个左子树的节点时自然就把右节点接到后面了。class Solution { public void flatten(TreeNode root) { if(root==null)return; Deque<原创 2021-02-08 12:53:34 · 94 阅读 · 0 评论 -
后序遍历DFS1.删除给定值的叶子节点(删除节点)
首先想这个题的普通节点怎么做,首先删除它的子节点的叶子节点,如果返回来时它自己成了叶子节点,则要删除它自己,所以很显然是后序遍历。然后就是怎么删除自己的问题,要删除自己,就返回null,然后让自己的父节点接到自己时将其删除。class Solution { public TreeNode removeLeafNodes(TreeNode root, int target) { if(root==null)return null; TreeNode left=rem原创 2021-01-24 17:30:50 · 289 阅读 · 0 评论 -
后序遍历DFS2.求两个节点在二叉树中的最近公共节点
要求两个节点的公共节点,则肯定是从这个节点原创 2021-01-24 14:48:59 · 126 阅读 · 0 评论 -
递归4.填充每个节点的下一个右侧指针116
从一个普通节点入手,首先这不是子节点可以完成的事情,不用创建递归函数,从头结点出发,交换左右一直到最后class Solution { public TreeNode invertTree(TreeNode root) { if(root==null)return null; TreeNode node=root.left; root.left=root.right; root.right=node; invertTr原创 2021-01-24 14:17:09 · 83 阅读 · 0 评论 -
层序遍历BFS5.层数最深的叶子节点的和
求层数最深的节点和,那也是一层的,直接利用层序遍历,返回最后一层的和,每层遍历开始前清空res,最后一层则不会被清空import java.util.LinkedList;class Solution { public int deepestLeavesSum(TreeNode root) { if(root==null)return 0; Queue<TreeNode> q=new LinkedList<TreeNode>();原创 2021-01-14 18:31:18 · 95 阅读 · 0 评论 -
层序遍历BFS4.二叉树的堂兄弟节点
这个题既然堂兄弟节点在同一层,就可以利用层序遍历来锁定一层,然后目的是找到这两个节点的父节点,如果找到两个节点且父节点不是同一个则返回true。如果都没找到则下一层。如果一层找到一个,则肯定不在一层,返回false。import java.util.LinkedList;class Solution { public boolean isCousins(TreeNode root, int x, int y) { if(root==null ||x==root.val || y=原创 2021-01-14 18:19:46 · 103 阅读 · 0 评论 -
层序遍历BFS3.二叉树的最大宽度
因为是求宽度,所以使用二叉树的层序遍历,由于要计算空节点,所以在遍历的过程中额外维护一个位置队列,在这一层的遍历开始时peek出最左的节点,然后每一个节点都算一次此时的最大宽度,最终遍历完之后得到这一层最大的宽度。在添加节点的时候要注意要顺便添加当前节点的2倍给左节点,添加当前节点的2倍加1给右节点。 import java.util.ArrayList; import java.util.LinkedList;class Solution { public int widthOfBina原创 2021-01-14 17:13:49 · 169 阅读 · 0 评论 -
层序遍历BFS2.N叉树
N叉树层序遍历 import java.util.ArrayList; import java.util.LinkedList;class Solution { public List<List<Integer>> levelOrder(Node root) { List<List<Integer>> res=new ArrayList<List<Integer>>(); if(root=原创 2021-01-14 16:44:06 · 77 阅读 · 0 评论 -
层序遍历BFS1.将节点层序输出
分行层序遍历如果要分层把list输出到res中(也就是一层完了再打印一层),就要在while中加一个for来控制到什么时候停止,一定要注意在加的时候看节点是否为空,是空continue,那怎么知道for循环中的size呢,就是看队列中的节点个数,在开始前的节点个数就是这一层所有的节点个数,全部循环完也就是这一层的下一层节点也全部添加进去了还要注意如果list长度不为0才能添加到res中,否则最后会多添加一个空list小技巧是创建一个list,然后每次添加完之后都令list=new ArrayList,原创 2021-01-14 15:36:55 · 285 阅读 · 0 评论 -
前序遍历DFS5.从叶节点开始的最大字符串
这个题很重要的就是因为最后删了一个节点,所以要叶子节点完了以后也不用return。记得reverse之后再比class Solution { String res="~"; public String smallestFromLeaf(TreeNode root) { if(root==null) return res; dfs(root,new StringBuilder()); return res; } public v原创 2021-01-14 02:12:51 · 118 阅读 · 0 评论 -
前序遍历DFS4.二叉树中某一值的路径plus
这个的路径是从任意节点开始到任意节点结束,但只能从上到下。这里有个非常重要的思想是从整体思考,思考一个普通节点的处理,因为是可以从任意节点开始,所以递归的是从头结点开始,从左节点开始,从右节点开始。(注意左右节点递归的是原函数)。头节点递归的是dfs函数,因为dfs函数其实就是从头结点开始了。class Solution { public int pathSum(TreeNode root, int sum) { if(root==null) return 0;原创 2021-01-14 01:35:05 · 111 阅读 · 0 评论 -
前序遍历DFS3.根到叶子节点数字之和
每条路径代表一个数字,数字是由每个节点的数字组成的。可以转换为每个节点的数字代表的是它的父节点的数字乘10加此节点的数字前面的题是到子节点返回它的值到父节点处理,而这个题是传父节点的值到子节点处理。class Solution { public int sumNumbers(TreeNode root) { if(root==null)return 0; return core(root,0); } public int core(TreeNo原创 2021-01-14 00:12:53 · 155 阅读 · 0 评论 -
前序遍历DFS2.二叉树中的最大路径和
注意是从任意节点出发,到达任意节点,这就意味着最后的结果是从某个节点出发上升到某个节点,然后又下降到某个节点的一个路径。枚举节点时将它的最大路径拆成三部分,算每一部分的贡献值,空节点贡献值为0,非空节点的贡献值为它的节点值与子节点中最大贡献值之和。递归过程就是先得到叶节点的最大贡献值,然后依次往上求最大贡献值,x=x.val+max(dfs(x.left),dfs(x.right)); 为什么是其中一个呢,因为如果往上传的话,就算出现也只能走一条路,而自己作为头结点的是全加起来。注意不用加单独对子节点的原创 2021-01-13 23:48:32 · 127 阅读 · 0 评论 -
前序遍历DFS1.二叉树中和为某一值的路径
二叉树中和为某一值的路径这个题首先想到的思路就是遍历所有的二叉树路径,然后找到其中符合的路径传入res中。而在传的时候需要传入一个list,所以建一个新的函数,在外面建立一个res,如果符合则传入list,直到前序遍历完所有的节点则返回res在core中的代码就是前序遍历,如果root是null则返回,然后处理,最后就是两个递归,但递归的时候要new一个新的list进去,因为如果一直传一个list,那所有的节点都在一个list中.在中间的处理步骤就是先将这个节点加入list中,然后用target的值原创 2020-11-27 19:06:57 · 174 阅读 · 0 评论 -
递归3.判断树的子结构/子树
树的子结构输入两颗树,判断树A是否为树B的子结构子结构也就是树A的头结点以及子树是B的一部分即可所以首先判断头结点是否相同,如果相同,则检查左子树或者右子树是否相同。如果不同,则直接检查左右子树的头结点与树A。整个检查过程可以使用递归,而最后递归的结束条件就是树A到达最底部变成null,则树A为子结构,若递归到最后B先到达底部而A没有,说明A不是B的子结构。public class Solution { public boolean HasSubtree(TreeNode root1,Tr原创 2020-11-24 20:13:10 · 309 阅读 · 0 评论 -
递归2.求二叉树的镜像
是一颗树变成它的镜像这个很简单,就是具体到每个节点看怎么变成它的镜像,先将左右子树交换,然后递归各自将左右子树进行镜像,如果发现到达最底部则返回public class Solution { public void Mirror(TreeNode root) { if(root==null){ return; } TreeNode temp=root.left; root.left=root.right;原创 2020-11-25 15:51:08 · 251 阅读 · 0 评论 -
递归1.求二叉树是否为镜像的226
求二叉树是否镜像求是否镜像和看是否为镜像非常像但又不一样求镜像只要进行下去肯定能交换过来。而看是否为镜像,需要在此时比较左右子树,所以需要写一个新的递归函数来实现,为什么不能在一个函数里操作比较两个子树,因为这样会用到a.left.val不要用两层属性。比较的时候先看两个是否都为null,都为则一起到底返回true,如果只有一个是null,则返回false。如果两个值相同则返回左的左子树和右的右子树。左的右子树和右的左子树。都是true则返回true,否则返回falsepublic class原创 2020-11-25 20:43:46 · 89 阅读 · 0 评论 -
中序遍历DFS3.二叉树的下一个节点
二叉树下一个节点依然是和遍历有关,找到中序遍历的下一个节点,节点中还拥有指向父节点的指针。分情况讨论,中序遍历也就是左中右如果节点有右子树,则下个节点是右子树的最左节点。如果节点没有右子树,且它为它父节点的左节点,则下个节点为它的父节点如果节点没有右子树,且它为它父节点的右节点,则下个节点是先找到一个为它父节点的左节点的节点,则下个节点就是这个节点的父节点。public class Solution { public TreeLinkNode GetNext(TreeLinkNode p原创 2020-11-10 10:58:40 · 91 阅读 · 0 评论 -
中序遍历DFS2.二叉搜索树与双向链表之间的转换
二叉搜索树和双向链表之间的转换这个题需要将二叉排序树中的节点,变成按顺序排序的双向链表。因为双向链表和树的每个节点都具有两个指针,而且都是排序的,所以可行。要做的就是把一个节点的一个指针指向前驱节点,一个指针指向后驱节点。当然了这个没有父节点,不能遍历有限的次数找到前驱和后继,所以是中序遍历。1.非递归版本非递归版本很好写,首先按照正常的中序遍历非递归写出来,然后就是在到达最左端节点之后,也就是while循环到node为空之后进入else,这时要处理pop出的节点cur,最后让cur等于它的右节点,千原创 2020-11-28 22:21:02 · 102 阅读 · 0 评论 -
中序遍历DFS4.查看序列是否是二叉搜索树的后序遍历
特点按照中序排列从小到大,且不出现重复节点。判断是否是排序二叉树只需要在中序遍历的过程中判断这次的遍历结果是否比上次的大即可。查看此序列是否是二叉搜索树的后序遍历很显然,二叉搜索树是按照中序排列从小到大,那它的后序遍历就是小大小的顺序。1.需要找到根节点,然后找到左子树和右子树的遍历,判断完之后递归判断左子树和右子树是否符合。2.判断过程就是右子树全部大于中大于左子树3.那怎么找到根节点,左子树,右子树,根节点是最后一个,第一个大于根节点的值就是右子树的开始。注:所以所有的类似给了二叉树遍历序原创 2020-11-27 16:38:17 · 118 阅读 · 0 评论 -
字符串->树 1.重建二叉树
重建二叉树输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。这个题的思路就是通过前序遍历和中序遍历找到左子树和右子树的前序遍历和中序遍历然后分别递归,一直递归到最后一个节点,创建一个新节点,然后返回创造其他节点。我原来写的算法是怎么确定遍历的起始位置和终止位置的呢,是靠数组复制,直接复制进去,其实不用,直接每次都传同一原创 2020-11-01 11:56:36 · 151 阅读 · 0 评论 -
遍历1.二叉树基础遍历
递归方式就使用的就是分治的思想,要用什么方式遍历取决于先输出还是先遍历左子树或遍历右子树,终止条件就是到最后,递归结束就可以对于1有子节点2,3来说,遍历顺序是122213331 每个节点经过三次。另两次是在左子树和右子树返回的时候非递归前序遍历准备一个栈,压入头结点,进入循环,若栈为空则退出。弹出一个元素,输出(这是第一次进入头结点),如果右子树不为空,则压入。如果左不为空再压左public void print(treeNode node){ Stack<treeNode> s原创 2020-11-26 13:10:16 · 164 阅读 · 0 评论 -
遍历2.序列化二叉树
序列化二叉树不同于把字符串变成二叉树,序列化是把二叉树变成字符串,使用前序遍历,用1个特殊字符表示空,然后递归实现。实现过程就是利用一个StringBuilder来拼接字符串,将sb和头结点传入递归函数中,正常前序遍历,在处理节点的时候,将它的值加一个节点结束符!拼接到sb中,递归拼接。最后返回sb。在原函数中返回sb.toStirng String Serialize(TreeNode root) { if(root==null){ return "#!";原创 2020-11-29 11:08:36 · 95 阅读 · 0 评论 -
中序遍历DFS.1.二叉排序树第k个结点
返回二叉搜索树的第k个节点中序遍历是从小到大的,返回第k个就行递归写递归的时候,视角应该是在最上面的那个节点,然后想象遍历它的左子树怎么样,如果在这个节点会怎么样,然后再遍历右子树,而不是以一个底层节点的视角来看。public class Solution { int seq=0; TreeNode KthNode(TreeNode pRoot, int k) { if(pRoot==null || k==0){ return null原创 2020-12-09 09:51:49 · 605 阅读 · 0 评论 -
后序遍历DFS3.平衡二叉树(树的深度)
求输入根节点的深度(最长路径)递归思路,如果把树分成三部分,求树的左树深度,求右树深度,则深度就为更大的一个加1.使用后序遍历,得到左和右的深度之后就可以了。public class Solution { public int TreeDepth(TreeNode root){ if(root==null){ return 0; } int ld=TreeDepth(root.left); int rd=Tr原创 2020-12-09 10:23:52 · 316 阅读 · 0 评论