每日一刷——二叉树——12.09
第一题:二叉树的层序遍历
题目描述:102. 二叉树的层序遍历 - 力扣(LeetCode)
我的思路:
拿到这个题目,我首先想到的是利用队列来模拟,给我二叉树的根节点,然后我来返回每一层的各个节点,但是为啥我甚至觉得这个题目给的输入就是按照层序遍历来给的呢??
然后感觉还有一个点就是咋返回成几个list嵌套
===>二叉树题目就是培养递归思维的
题目分析:
由于先进先出,取出一个节点之后,就再往里边添加它自己的左右孩子,这样左右孩子的顺序还是在本层节点的后边,但是在下一层其他节点的前面
===》1.怎么返回成几个list嵌套?那就每一层安排一个list,这个完了之后就添加到答案数组中,
===》2.怎么知道这一层有多少个数字? 其实就是上一层执行了往队列里边添加数字了之后,它自己就走了,上一层的数字都走了之后,就可以发现此时,队列里边就是下一层即将要执行的数字,所以就定义一个count变量,将count=queue.size()
笑死,每次都感觉自己的思维能力不够,哎,还要多模仿多练习啊.....
知识点回顾:
1.List
在获得List对象之后,就可以对其进行元素的添加、删除、修改和查询等操作了。下面是一些常用的List元素操作方法:
===>添加元素:
向List集合中添加元素,我们可以使用add()方法、addAll()方法和ListIterator的add()方法。这些方法分别具有以下特点:
add()方法:将指定元素添加到List的末尾;
addAll()方法:将指定集合中的所有元素添加到List的末尾;
ListIterator的add()方法:将指定元素插入到ListIterator当前位置。
2.queue
当使用LinkedList时:
import java.util.LinkedList;
import java.util.Queue;
public class LinkedListExample {
public static void main(String[] args) {
Queue<Integer> queue = new LinkedList<>();
// 向队列添加元素
queue.add(1);
queue.add(2);
// 使用poll和peek方法
System.out.println(queue.poll()); // 输出: 1
System.out.println(queue.peek()); // 输出: 2
}
}
1.E poll()
: 移除并返回队列头部的元素,如果没有元素则返回null
。
2.E peek()
: 返回队列头部的元素但不移除它,如果没有元素则返回null。
题解:
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> ans =new ArrayList<>();
Queue<TreeNode> queue =new LinkedList<>();
queue.add(root);
if(root == null)
return ans;
else{ //可是这个应该是需要记录每一行究竟有多少个吧
while(!queue.isEmpty()){
int count =queue.size();
//要用两个数组
List<Integer> list =new ArrayList<>();
while(count >0){
TreeNode temp =queue.poll();
list.add(temp.val);
if(temp.left!=null)
queue.add(temp.left);
if(temp.right!=null){
queue.add(temp.right);
}
count--;
}
ans.add(list);
}
return ans;
}
}
}
第二题:二叉树的最大深度
题目描述:104. 二叉树的最大深度 - 力扣(LeetCode)
我的思路:
感觉是深度优先遍历,用一个栈?
好吧,感觉根本不需要用到栈,因为用栈是可以储存节点,这样便于我们把节点打印出来,现在我们并不需要打印,所以也就没什么必要用到栈,好吧。
呜呜呜
题目分析:
这个题目的思路就是:
用一个外部的变量来定义每一条路上的深度,然后求一下最大值,
知识点回顾:
1.stack的常见用法:
我的题解:
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public int maxDepth(TreeNode root) {
if(root==null)
return 0;
//这里是往下边递归,然后发现有没有最大值
else{
return traverse(root);
}
}
public static int depth=0;
//往下遍历
public static int traverse(TreeNode node){
depth++;
while(node!=null){
traverse(node.left);
traverse(node.right);
}
}
}
改进上一次的代码:
1.要用一个depth求每一条路的最大深度,
还要用一个res记录目前的最大深度
2.那么res什么时候使用,就是当判断到自己什么时候是空了,自己空了,就更新这个值
3.然后就是在递归遍历左边和右边中间或者两旁的一些代码,就是用来思考这个节点的前序时应该做什么操作,后序做什么操作,中序做什么操作
4.这里又忘记返回了,这里为啥要返回呢? 因为到达了末端了,下边的代码只有往下走的功能,到达尽头了还不回头,就要时间超出限制了。
if(node==null){
res=Math.max(res,depth);
return;
时间超时了哈,栓Q
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public int maxDepth(TreeNode root) {
if(root==null)
return 0;
//这里是往下边递归,然后发现有没有最大值
else{
traverse(root);
return res;
}
}
public static int depth=0;
public static int res=0; //存放每一条路上的最大值
//往下遍历
public static void traverse(TreeNode node){
if(node==null){
res=Math.max(res,depth);
return; //这里又忘记返回了,这里为啥要返回呢? 因为到达了末端了,下边的代码只有往下走的功能,到达尽头了还不回头,就要时间超出限制了
}
while(node!=null){
depth++;
traverse(node.left);
traverse(node.right);
depth--;
//把它想象成一个指针
}
}
}
感觉自己的思路很乱,就是不知道从何开始想这个题目,然后很多思路糅合在一起,像一团乱码
正确题解:
没事,我们还有一种思路哈,惹惹
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public int maxDepth(TreeNode root) {
if(root ==null)
return 0;
int leftMax =maxDepth(root.left);
int rightMax =maxDepth(root.right);
int res =Math.max(leftMax,rightMax) +1;
return res;
}
}
往下不断递归,上一层应该是下边两层里边的最大值的深度+1,也就是说这个int的位置放在,左右都求完深度之后,又回到了自己这里,然后深度+1
第三题:二叉树的锯齿形层序遍历
题目描述:103. 二叉树的锯齿形层序遍历 - 力扣(LeetCode)
题目分析:
其实和第一题很类似,但是要用双端队列写,然后添加一个flag,用于控制此时的方向
题解:
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public List<List<Integer>> zigzagLevelOrder(TreeNode root) {
List<List<Integer>> ans =new ArrayList<>();
if(root==null){
return ans;
}
LinkedList<TreeNode> deque =new LinkedList<>(); //双端队列
deque.add(root); //先把头节点放进去
int size=0;
boolean isHead =true ;//用来控制锯齿的顺序
while(!deque.isEmpty()){
size =deque.size();//先得到size
List<Integer> curLevel = new ArrayList<>();
for(int i =0;i<size;i++){ //搞size次
TreeNode cur =isHead ? deque.pollFirst() :deque.pollLast();
curLevel.add(cur.val);
if(isHead){
if(cur.left !=null){
deque.addLast(cur.left);
}
if(cur.right!=null){
deque.addLast(cur.right);
}
}else{
if(cur.right!=null){
deque.addFirst(cur.right);
}
if(cur.left !=null){
deque.addFirst(cur.left);
}
}
}
ans.add(curLevel);
isHead =!isHead;
}
return ans;
}
}
没办法,多练习吧
原文地址:https://blog.csdn.net/2301_80073593/article/details/144359928
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!