力扣(LeetCode)刷题第144和114题:二叉树的遍历和相关操作!

本篇文章给大家分享一下二叉树的相关算法。
二叉树

前言

题目地址(难度:简单):二叉树前序遍历
题目地址(难度:中等): 二叉树展开为链表

一、题目介绍

1.1二叉树前序遍历

我们都知道二叉树有三种遍历方式,分别是前序遍历、中序遍历和后序遍历,每一种遍历都有不同的性质,大家在后期的做题过程中可能会用到一些遍历的性质,所以请注意这块的性质!

三种遍历都是类似的,就是输出的顺序有所不同,会一种基本其余的两种也就会写了。

示例 1:

输入:root = [1,null,2,3]
输出:[1,2,3]

示例 2:

输入:root = []
输出:[]

1.2 二叉树展开为链表

给定一个二叉树,原地将它展开为一个单链表。其实仔细分析题目,这就是前序输出二叉树,这里介绍的也是最容易想到的思路,官方还给了另外的两种思路,大家可以到这里查看!
示例 1:
在这里插入图片描述

二、解题思路

1.分析题目

当拿到二叉树类型的题目的时候,就要往这方面的内容进行思考,比如三种遍历方式、还有就是深度优先搜索和广度优先搜索这块思考,基本常见的也就是这几种题目。

2.二叉树的前序遍历

对于二叉树的前序遍历,我们可以使用递归和迭代的方式进行遍历。

2.2.1递归

class Solution {
    public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> res = new ArrayList<Integer>();
        preorder(root, res);//递归调用
        return res;
    }

    public void preorder(TreeNode root, List<Integer> res) {
        if (root == null) {
            return;
        }
        res.add(root.val);//根节点
        preorder(root.left, res);//左子树
        preorder(root.right, res);//右子树
    }
}

复杂度分析

  • 时间复杂度:O(n)O(n),其中 nn 是二叉树的节点数。每一个节点恰好被遍历一次。
  • 空间复杂度:O(n)O(n),为递归过程中栈的开销,平均情况下为 O(\log n)O(logn),最坏情况下树呈现链状,为
    O(n)O(n)。

2.2.2迭代

class Solution {
    public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> res = new ArrayList<Integer>();
        if (root == null) {
            return res;
        }

        Deque<TreeNode> stack = new LinkedList<TreeNode>();
        TreeNode node = root;
        while (!stack.isEmpty() || node != null) {
            while (node != null) {
                res.add(node.val);
                stack.push(node);
                node = node.left;
            }
            node = stack.pop();
            node = node.right;
        }
        return res;
    }
}

复杂度分析

  • 时间复杂度:O(n)O(n),其中 nn 是二叉树的节点数。每一个节点恰好被遍历一次。
  • 空间复杂度:O(n)O(n),为迭代过程中显式栈的开销,平均情况下为 O(\log n)O(logn),最坏情况下树呈现链状,为
    O(n)O(n)。

3.代码

3.1题目一:二叉树前序遍历

Java代码详细注释

class Solution {
    public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> result = new ArrayList<>();//创建list
        preTree(root,result);//递归遍历
        return result;
    }
    public void preTree(TreeNode root,List<Integer> result){
        if(root!=null){
            result.add(root.val);
            preTree(root.left,result);
            preTree(root.right,result);
        }
    }
}

3.2题目二: 二叉树展开为链表

将二叉树展开为单链表之后,单链表中的节点顺序即为二叉树的前序遍历访问各节点的顺序。因此,可以对二叉树进行前序遍历,获得各节点被访问到的顺序。由于将二叉树展开为链表之后会破坏二叉树的结构,因此在前序遍历结束之后更新每个节点的左右子节点的信息,将二叉树展开为单链表。
Java代码详细注释

class Solution {
    public void flatten(TreeNode root) {
        List<TreeNode> list = new ArrayList<>();
        preTree(root,list);//前序遍历二叉树
        int size = list.size();//链表的长度
        for(int i=1;i<size;i++){
            TreeNode pre = list.get(i-1),curr = list.get(i);
            pre.left = null;
            pre.right = curr;
        }
    }
    //二叉树的递归先序遍历
    public void preTree(TreeNode root,List<TreeNode> list){
        if(root!=null){
            list.add(root);
            preTree(root.left,list);
            preTree(root.right,list);
        }
    }
}

三、总结

树这块的题目基本都是有套路可寻的,所以大家在平时多加练习的同时,一定要熟记相关的套路,思路找好,模板一套,齐活!
在这里插入图片描述

记录时间:2020年12月22日

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值