二叉树
层序遍历
二叉树的遍历方式:
- 深度优先遍历(递归和迭代)
栈先进后出适合模拟深度优先遍历也就是递归的逻辑 - 层序遍历
队列先进先出,符合一层一层遍历的逻辑
Leecode
一口气刷完层序遍历十道题
102. 二叉树层序遍历
思路:
从根节点开始,将元素放入栈,然后出栈,判断出栈的元素是否存在左右的节点,存在就将元素依次放入队列(先入先出)
满老师的视频讲解比看文字更容易懂
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> res = new ArrayList<List<Integer>>();
Queue<TreeNode> queue = new LinkedList<TreeNode>();
// 需要考虑一种特殊情况
if(root==null){
return res;
}
queue.offer(root);
int c1 =1; // c1记录本层的节点数
while(!queue.isEmpty()){
List<Integer> level = new ArrayList<Integer>();
int c2 =0; // c2记录下一层的节点数
for(int i=0;i<c1;i++){
TreeNode pop = queue.poll();
level.add(pop.val);
if(pop.left!=null){
queue.offer(pop.left);
c2++;
}
if(pop.right!=null){
queue.offer(pop.right);
c2++;
}
}
c1 = c2;
res.add(level);
}
return res;
}
}
上面的c1和c2其实不需要自己去赋值
c
1
c1
c1:当层元素的个数,就是开始poll出元素前队列的大小
所以就不需要
c
2
c2
c2
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> res = new ArrayList<List<Integer>>();
Queue<TreeNode> queue = new LinkedList<TreeNode>();
// 需要考虑一种特殊情况
if(root==null){
return res;
}
queue.offer(root);
// c1记录本层的节点数
while(!queue.isEmpty()){
List<Integer> level = new ArrayList<Integer>();
int c1 =queue.size(); // c2记录下一层的节点数
for(int i=0;i<c1;i++){
TreeNode pop = queue.poll();
level.add(pop.val);
if(pop.left!=null){
queue.offer(pop.left);
}
if(pop.right!=null){
queue.offer(pop.right);
}
}
res.add(level);
}
return res;
}
}
107. 二叉树的层次遍历II
题目描述
思路一:只需要在原来的基础上,将结果反转,只需要在原本的
r
e
t
u
r
n
return
return
r
e
s
;
res;
res;前面加上反转的代码:
//开始反转
List<List<Integer>> reverse = new ArrayList<List<Integer>>();
for(int i=res.size()-1;i>=0;i--){
reverse.add(res.get(i));
}
return reverse;
思路二:利用链表,每一次添加的时候都向头部添加
class Solution {
public List<List<Integer>> levelOrderBottom(TreeNode root) {
//***************************主要改了这一句***********//
LinkedList<List<Integer>> res = new LinkedList<>();
//****************************************************//
Queue<TreeNode> queue = new LinkedList<TreeNode>();
// 需要考虑一种特殊情况
if(root==null){
return res;
}
queue.offer(root);
int c1 =1; // c1记录本层的节点数
while(!queue.isEmpty()){
List<Integer> level = new ArrayList<Integer>();
int c2 =0; // c2记录下一层的节点数
for(int i=0;i<c1;i++){
TreeNode pop = queue.poll();
level.add(pop.val);
if(pop.left!=null){
queue.offer(pop.left);
c2++;
}
if(pop.right!=null){
queue.offer(pop.right);
c2++;
}
}
c1 = c2;
res.addFirst(level);
}
return res;
}
}
199.二叉树的右视图
- 解法:队列,迭代。
每次返回每层的最后一个字段即可。
class Solution {
public List<Integer> rightSideView(TreeNode root) {
List<Integer> list = new ArrayList<>();
Deque<TreeNode> que = new LinkedList<>();
if (root == null) {
return list;
}
que.offer(root);
int c1=1;
while (!que.isEmpty()) {
int c2=0;
for (int i = 0; i < c1; i++) {
TreeNode poll = que.poll();
if (poll.left != null) {
que.add(poll.left);
c2++;
}
if (poll.right != null) {
que.add(poll.right);
c2++;
}
if (i == c1 - 1) {
list.add(poll.val);
}
}
c1=c2;
}
return list;
}
}
637.二叉树的层平均值
List<Double> res = new ArrayList<Double>();
Queue<TreeNode> queue = new LinkedList<TreeNode>();
......
......
while(!queue.isEmpty()){
double sum=0.0;
int c2 =0; // c2记录下一层的节点数
for(int i=0;i<c1;i++){
TreeNode pop = queue.poll();
sum+=pop.val;
......
......
res.add(sum/c1);
c1 = c2;
}
return res;
429.N叉树的层序遍历
515. 在每个树行中找最大值
116. 填充每个节点的下一个右侧节点指针
117. 填充每个节点的下一个右侧节点指针 II
直接用上一题的代码
104. 二叉树的最大深度
二叉树的遍历方式:
- 深度优先遍历(递归和迭代)
栈先进后出适合模拟深度优先遍历也就是递归的逻辑 - 层序遍历
队列先进先出,符合一层一层遍历的逻辑
1.深度优先遍历—递归
class Solution {
public int maxDepth(TreeNode root) {
if(root == null){
return 0;
}
int d1 = maxDepth(root.left);
int d2 = maxDepth(root.right);
return Integer.max(d1,d2) + 1;
}
}
-
深度优先遍历—迭代(栈)
后序遍历,栈中最大元素就是最大深度 -
层序遍历
111. 二叉树的最小深度
满老师讲过
1.递归
2.层序遍历
226. 翻转二叉树
深度优先遍历----递归:
class Solution {
public TreeNode invertTree(TreeNode root) {
fn(root);
return root;
}
public void fn(TreeNode root){
if(root == null){
return;
}
TreeNode t = root.left;
root.left = root.right;
root.right = t;
fn(root.left);
fn(root.right);
}
}
层序遍历:
遍历每一个节点的时候,交换其左右两个节点
class Solution {
public TreeNode invertTree(TreeNode root) {
Queue<TreeNode> queue = new LinkedList<TreeNode>();
// 需要考虑一种特殊情况
if(root==null){
return root;
}
queue.offer(root);
// c1记录本层的节点数
while(!queue.isEmpty()){
int c1 =queue.size(); // c2记录下一层的节点数
for(int i=0;i<c1;i++){
TreeNode pop = queue.poll();
swap(pop);
if(pop.left!=null){
queue.offer(pop.left);
}
if(pop.right!=null){
queue.offer(pop.right);
}
}
}
return root;
}
public void swap(TreeNode root){
TreeNode t = root.left;
root.left = root.right;
root.right = t;
}
}
101. 对称二叉树
*/
class Solution {
public boolean isSymmetric(TreeNode root) {
return check(root.left,root.right);
}
public boolean check(TreeNode left, TreeNode right){
//都为null
if(left==null&&right ==null){
return true;
}
// 只有其中之一为null
if(left==null||right==null){
return false;
}
// 都不为null,有值
//1.不等
if(left.val != right.val){
return false;
}
//2.相等
//就让左节点的左边 和 右节点的右边
// 左节点的右边 和 右节点的左边
return check(left.left,right.right)&&check(left.right,right.left);
}
}