leetcode刷题 | 关于二叉树的题型总结1

简介: 二叉树的题型总结

leetcode刷题 | 关于二叉树的题型总结1

题目连接

919. 完全二叉树插入器 - 力扣(LeetCode)

515. 在每个树行中找最大值 - 力扣(LeetCode)

513. 找树左下角的值 - 力扣(LeetCode)

199. 二叉树的右视图 - 力扣(LeetCode)

814. 二叉树剪枝 - 力扣(LeetCode)

297. 二叉树的序列化与反序列化 - 力扣(LeetCode)

完全二叉树插入器

classCBTInserter {

   TreeNoderoot;

   // 存入不完整结构的节点

   Deque<TreeNode>deq;

   publicCBTInserter(TreeNoderoot) {

       this.root=root;

       deq=newArrayDeque();

       //添加到队列尾部

       deq.offer(root);

      while(deq.peek().left!=null&&deq.peek().right!=null){

          TreeNodetemp=deq.poll();

          deq.offer(temp.left);

          deq.offer(temp.right);

      }        

   }

   publicintinsert(intv) {

       TreeNodenode=deq.peek();

       if(node.left==null) node.left=newTreeNode(v);

       else{

           node.right=newTreeNode(v);

           deq.poll();

           deq.offer(node.left);

           deq.offer(node.right);

       }

       returnnode.val;

   }

 

   publicTreeNodeget_root() {

       returnroot;

   }

}

在每个树行中找最大值

dfs解法,按照中左右顺序遍历

classSolution {

   List<Integer>res=newArrayList();

 

   publicList<Integer>largestValues(TreeNoderoot) {

       dfs(root,0);

       returnres;

   }

   publicvoiddfs(TreeNoderoot,intdepth){

       if(root==null) return;

       if(res.size() ==depth){

           res.add(root.val);

       }

       res.set(depth,Math.max(root.val,res.get(depth)));

       if(root.left!=null) dfs(root.left,depth+1);

       if(root.right!=null) dfs(root.right,depth+1);

   }

}

层序遍历,层序遍历具有通用性,在之后几道题中都可以这么做

classSolution {  

   publicList<Integer>largestValues(TreeNoderoot) {

       List<Integer>res=newArrayList();

       Deque<TreeNode>deq=newArrayDeque();

       if(root==null) returnres;

       deq.add(root);

       while(!deq.isEmpty()){

           intsize=deq.size();

           inttemp=Integer.MIN_VALUE;

           while(size-->0){

               TreeNodenode=deq.poll();

               temp=Math.max(temp,node.val);

               if(node.left!=null)  deq.add(node.left);

               if(node.right!=null) deq.add(node.right);

           }

           res.add(temp);

       }

       returnres;      

   }

}

找树左下角的值

classSolution {

   publicintfindBottomLeftValue(TreeNoderoot) {

       if(root==null) return-1;

       Deque<TreeNode>deq=newArrayDeque();

       deq.add(root);

       intres=root.val;

       while(!deq.isEmpty()){

           intsize=deq.size();

           for(inti=0;i<size;i++){

               TreeNodenode=deq.poll();

               if(i==0) res=node.val;

               if(node.left!=null) deq.add(node.left);

               if(node.right!=null) deq.add(node.right);

           }

       }

       returnres;

   }

}

二叉树的右视图

classSolution {

   publicList<Integer>rightSideView(TreeNoderoot) {

        List<Integer>res=newArrayList<>();

       if(root==null) returnres;

       Deque<TreeNode>deq=newArrayDeque<>();

       deq.add(root);

       

       while (!deq.isEmpty()){

           intsize=deq.size();

           for (inti=0;i<size;i++){

               TreeNodenode=deq.poll();

               if (i==size-1) res.add(node.val);

               if (node.left!=null) deq.add(node.left);

               if (node.right!=null) deq.add(node.right);

           }

       }

       returnres;

   }

}

二叉树剪枝

递归结束条件:左子树为空,右子树为空,当前节点的值为 0,同时满足时,才表示以当前节点为根二叉树的所有节点都为 0,需要将这棵子树移除,返回空

classSolution {

   publicTreeNodepruneTree(TreeNoderoot) {

       if (root==null) returnnull;

       root.left=pruneTree(root.left);

       root.right=pruneTree(root.right);

       if (root.left==null&&root.right==null&&root.val==0) returnnull;

       returnroot;

   }

}

DFS,从评论区大佬的评论里知道了StringJoiner类,做一个简单的解释

StringJoiner是java.util包下的一个工具类,jdk1.8出来的

作用是在构造字符串时,可以自动添加前缀、后缀及分隔符,而不需要自己去实现这些添加字符的逻辑

StringJoiner sj = new StringJoiner(",", "[", "]");

代表每一个字符的后缀为,前缀开始为[ , 后缀结束为 ]

如果 sj.add("1").add("2").add("3");

那么toString() 输出:[1,2,3]

importjava.util.*;

publicclassCodec {

   // Encodes a tree to a single string.

   publicStringserialize(TreeNoderoot) {

       if (root==null) return"";

       Deque<TreeNode>deq=newArrayDeque<>();

       // 可以提供后缀的末尾

       StringJoinersj=newStringJoiner(",");

       deq.offer(root);

       sj.add(Integer.toString(root.val));

       while (!deq.isEmpty()){

           intsize=deq.size();

           while (size-->0){

               TreeNodenode=deq.poll();

               if (node.left!=null){

                   deq.add(node.left);

                   sj.add(Integer.toString(node.left.val));

               }elsesj.add("null");

               if (node.right!=null){

                   deq.add(node.right);

                   sj.add(Integer.toString(node.right.val));

               }elsesj.add("null");

           }

       }

       returnsj.toString();

   }

 

   // Decodes your encoded data to tree.

   publicTreeNodedeserialize(Stringdata) {

       if (data=="") returnnull;

       String[] strings=data.split(",");

       Deque<TreeNode>deq=newArrayDeque<>();

       TreeNoderoot=newTreeNode(Integer.parseInt(strings[0]));

       deq.add(root);

       intindex=1; //定位当前位置,遍历顺序为中左右

       intl=strings.length;

       while(index<l){

           TreeNodenode=deq.poll();

           if (!strings[index].equals("null")){

               TreeNodeleft=newTreeNode(Integer.parseInt(strings[index]));

               node.left=left;

               deq.add(left);

           }

           index++; //找右节点

           if (index<l&&!strings[index].equals("null")){

               TreeNoderight=newTreeNode(Integer.parseInt(strings[index]));

               node.right=right;

               deq.add(right);

           }

           index++; //找左节点

       }

       returnroot;

   }

}

BFS解法

publicclassCodec {

   // Encodes a tree to a single string.

   publicStringserialize(TreeNoderoot) {

       StringBuilderstringBuilder=newStringBuilder();

       returnappendstr(root,stringBuilder).toString();

 

   }

   privateStringBuilderappendstr(TreeNodenode,StringBuilderstringBuilder){

       if (node==null) returnstringBuilder.append("null,");

       else {

           // 中左右

           stringBuilder.append(Integer.toString(node.val)+",");

           stringBuilder=appendstr(node.left,stringBuilder);

           stringBuilder=appendstr(node.right,stringBuilder);

       }

       returnstringBuilder;

   }

 

   // Decodes your encoded data to tree.

   publicTreeNodedeserialize(Stringdata) {

       String[] strings=data.split(",");

       // 速度更快

       List<String>nodes=newLinkedList<>(Arrays.asList(strings));

       returntotree(nodes);

   }

   publicTreeNodetotree(List<String>nodes){

       if (nodes.get(0).equals("null")){

           nodes.remove(0);

           return  null;

       }

       TreeNoderoot=newTreeNode(Integer.parseInt(nodes.get(0)));

       nodes.remove(0);

       root.left=totree(nodes);

       root.right=totree(nodes);

       returnroot;

   }

}


相关文章
|
28天前
|
Unix Shell Linux
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
本文提供了几个Linux shell脚本编程问题的解决方案,包括转置文件内容、统计词频、验证有效电话号码和提取文件的第十行,每个问题都给出了至少一种实现方法。
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
|
28天前
|
数据采集 负载均衡 安全
LeetCode刷题 多线程编程九则 | 1188. 设计有限阻塞队列 1242. 多线程网页爬虫 1279. 红绿灯路口
本文提供了多个多线程编程问题的解决方案,包括设计有限阻塞队列、多线程网页爬虫、红绿灯路口等,每个问题都给出了至少一种实现方法,涵盖了互斥锁、条件变量、信号量等线程同步机制的使用。
LeetCode刷题 多线程编程九则 | 1188. 设计有限阻塞队列 1242. 多线程网页爬虫 1279. 红绿灯路口
|
12天前
【LeetCode 31】104.二叉树的最大深度
【LeetCode 31】104.二叉树的最大深度
12 2
|
12天前
【LeetCode 29】226.反转二叉树
【LeetCode 29】226.反转二叉树
12 2
|
12天前
【LeetCode 28】102.二叉树的层序遍历
【LeetCode 28】102.二叉树的层序遍历
10 2
|
12天前
【LeetCode 43】236.二叉树的最近公共祖先
【LeetCode 43】236.二叉树的最近公共祖先
10 0
|
12天前
【LeetCode 38】617.合并二叉树
【LeetCode 38】617.合并二叉树
8 0
|
12天前
【LeetCode 37】106.从中序与后序遍历构造二叉树
【LeetCode 37】106.从中序与后序遍历构造二叉树
9 0
|
12天前
【LeetCode 34】257.二叉树的所有路径
【LeetCode 34】257.二叉树的所有路径
8 0
|
12天前
【LeetCode 32】111.二叉树的最小深度
【LeetCode 32】111.二叉树的最小深度
10 0