Leetcode刷题注意点:二叉树

时间复杂度:一个句子被执行多少次。 

空间复杂度:一个算法在运行过程中临时占用存储空间大小的量度

列表可以用.append() 添加数据

字符串 用 s += q 这个写法。

03

此题关键是哈希表的运用。

dic = set() 表示取出nums中的key 并且set里面元素不重复

 53-I,53-II排序数组

重点是 排序。可以选用二分法

遇到排序的数组,从左右两边进行查找速度快。

时间复杂度 O(logN) : 二分法为对数级别复杂度。
空间复杂度 O(1) : 几个变量使用常数大小的额外空间。

Python 没有内置对数组的支持,但可以使用 Python 列表代替。

04. 二维数组中的查找

左下角的重要性。

32 -   (I- III). 从上到下打印二叉树 III

这三题二叉树!

仔细学习二叉树:

目录

03

 53-I,53-II排序数组

04. 二维数组中的查找

32 -   (I- III). 从上到下打印二叉树 III

仔细学习二叉树:

二叉树递归 (引入栈)

二叉树的非递归      迭代法(引入栈)

二叉树层序遍历(引入队列)

 反转二叉树

对称二叉树(后序遍历)

二叉树的深度和高度(用后序)

完全二叉树的节点数量(后序遍历)

平衡二叉树(后序遍历)

 二叉树的所有路径(前序遍历)

 二叉树求左叶子之和(后序遍历)

 求树左下角的值

迭代法(层序遍历)

递归法

二叉树路径之和

递归法(没有中的处理逻辑,什么遍历方法都行)

 迭代

从中序与后序遍历序列构造二叉树

 最大二叉树(构造树一般采用的是前序遍历,因为先构造中间节点,然后递归构造左子树和右子树。)

合并二叉树(前序遍历)

二叉搜索树的搜索

 验证二叉搜索树

二叉搜索树的最小绝对差(中序遍历)

 二叉树的最近公共祖先

二叉搜索树的最近公共祖先(递归 前序遍历)

二叉搜索树中的插入操作

 修剪二叉搜索树

将有序数组转换为二叉搜索树

 把二叉搜索树转换为累加树

学习教辅:代码随想录 (programmercarl.com)

二叉树递归 (引入栈)

递归遍历是深度优先搜索的一部分。 

递归参数一般是:一个根节点,一个数组(用来放遍历的结果)

终止条件:遇到null则返回

单层递归逻辑:前序(中左右),中序(左中右),后序(左右中)

144,145,94题 

 或

二叉树的非递归      迭代法(引入栈)

前序(中左右)遍历时,输入栈中的节点先右节点,再左节点

步骤:

先传入二叉树,就是传入根节点

定义一个栈,放入二叉树的节点,节点里面通常是个结构体,里面有个value来存放元素,还有两个指针(一个左孩子一个右孩子)

在定义一个数组,用于存放遍历的结果。

根节点入栈,开始循环处理这个栈,只要栈不为空就一直执行{

从栈里弹出根节点,如果不为空,则加入数组;若为空,就进入下一次循环;(中)

把节点的右孩子放入(右)

再放入节点的左孩子(左)

}

后序遍历:(左右中)                 

中左右(前序)---(中右左)----左右中

中序遍历:(左中右)

遍历的节点和要处理的节点不一样。

步骤:

1.一直访问左边的元素,左边的元素访问到叶节点(即继续往左访问,没用元素了)

2.弹出元素

3.再看弹出的右元素,不为空,栈记录遍历过的右元素;继续看右元素的左右节点为空,则弹出;

二叉树层序遍历(引入队列)

就是图论里的广度优先搜索

步骤:

1.根节点加入队列,记录队列的size(表示这一层二叉树里面有几个元素)

2.弹出根节点,根节点的左右孩子加入队列,记录队列size(区分队列里面哪些元素是第二层的,哪些是第三层的)

3.弹出左孩子,队列再加入左孩子的两个子孩子

 反转二叉树

指针做交换,不只是值

用前序/后序  比较合适

用递归,步骤:

1.确定递归函数的参数和返回值

2.确定终止条件(碰见null)

3.确定单层递归的逻辑(先前序遍历,所以先进行交换左右孩子节点,然后反转左子树,反转右子树)

对称二叉树(后序遍历)

1.左子树的头节点和右子树的头节点 传入(遍历两棵树而且要比较内侧和外侧节点,所以准确的来说是一个树的遍历顺序是左右中,一个树的遍历顺序是右左中。

2.确定终止条件

递归法

二叉树的深度和高度(用后序)

深度:二叉树中任意一个节点到根节点的距离。

求高度:后序遍历(左右中)  从底往上去遍历

求深度:前序遍历   (从上往下去遍历)

所以根节点的高度就是二叉树的最大深度。

1.确定递归函数的参数和返回值:参数就是传入树的根节点,返回就返回这棵树的深度,所以返回值为int类型

2.确定终止条件:如果为空节点的话,就返回0,表示高度为0。

3.确定单层递归的逻辑:先求它的左子树的深度,再求右子树的深度,最后取左右深度最大的数值 再+1 (加1是因为算上当前中间节点)就是目前节点为根节点的树的深度。

二叉树的最小深度(后序遍历)

最小深度:从根节点到最近叶子节点的最短路径上的节点数量。

完全二叉树的节点数量(后序遍历)

当成普通二叉树进行后序遍历

用满二叉树的特性

平衡二叉树(后序遍历)

定义:一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过1

 二叉树的所有路径(前序遍历)

中左右+回溯算法

 二叉树求左叶子之和(后序遍历)

递归的遍历顺序为后序遍历(左右中),是因为要通过递归函数的返回值来累加求取左叶子数值之和。

递归三部曲:

1.确定递归函数的参数和返回值

判断一个树的左叶子节点之和,那么一定要传入树的根节点,递归函数的返回值为数值之和,所以为int

使用题目中给出的函数就可以了。

2.确定终止条件

如果遍历到空节点,那么左叶子值一定是0

3.确定单层递归的逻辑

当遇到左叶子节点的时候,记录数值,然后通过递归求取左子树左叶子之和,和 右子树左叶子之和,相加便是整个树的左叶子之和。

 求树左下角的值

给定一个二叉树,在树的最后一行找到最左边的值。

迭代法(层序遍历)

递归法

求深度最大的叶子节点

1.首先定义全局变量,用来定义二叉树的最大深度;定义一个result,记录节点里的值

定义函数的返回值;

2.终止条件:当遇到叶子节点的时候,就需要统计一下最大的深度了,所以需要遇到叶子节点来更新最大深度。

3.确定单层逻辑:在找最大深度的时候,递归的过程中依然要使用回溯。

二叉树路径之和

递归法(没有中的处理逻辑,什么遍历方法都行)

1.遍历的路线,并不要遍历整棵树,所以递归函数需要返回值,可以用bool类型表示。

2.终止条件:一个节点的左为空,右为空,count=0,return true

如果count !=0 ,return false

3.单层逻辑:如果左不为空,count-左节点,像左去递归;

 迭代

从中序与后序遍历序列构造二叉树

 中序:左中右

后序:左右中   (最后一个节点一定是中节点)

说到一层一层切割,就应该想到了递归。

来看一下一共分几步:

  • 第一步:如果数组大小为零的话,说明是空节点了。

  • 第二步:如果不为空,那么取后序数组最后一个元素作为节点元素。

  • 第三步:找到后序数组最后一个元素在中序数组的位置,作为切割点

  • 第四步:切割中序数组,切成中序左数组和中序右数组 (顺序别搞反了,一定是先切中序数组)

  • 第五步:切割后序数组,切成后序左数组和后序右数组

  • 第六步:递归处理左区间和右区间

 最大二叉树(构造树一般采用的是前序遍历,因为先构造中间节点,然后递归构造左子树和右子树。)

最大二叉树定义:

  • 二叉树的根是数组中的最大元素。
  • 左子树是通过数组中最大值左边部分构造出的最大二叉树。
  • 右子树是通过数组中最大值右边部分构造出的最大二叉树。

 1. 确定递归函数的参数和返回值

参数传入的是存放元素的数组,返回该数组构造的二叉树的头结点,返回类型是指向节点的指针。

2. 确定终止条件

题目中说了输入的数组大小一定是大于等于1的,所以我们不用考虑小于1的情况,那么当递归遍历的时候,如果传入的数组大小为1,说明遍历到了叶子节点了。

那么应该定义一个新的节点,并把这个数组的数值赋给新的节点,然后返回这个节点。 这表示一个数组大小是1的时候,构造了一个新的节点,并返回。

3.确定单层递归的逻辑

这里有三步工作

1)先要找到数组中最大的值和对应的下标, 最大的值构造根节点,下标用来下一步分割数组

2)最大值所在的下标左区间 构造左子树

3)最大值所在的下标右区间 构造右子树

用下标

合并二叉树(前序遍历)

前中后遍历都是可以的。

二叉搜索树的搜索

(所有节点)

递归法

 验证二叉搜索树

中序遍历(左中右)

将元素保存到数组上,判断数组是不是单调递增的

看左子树是不是一个合法的,所以self.traversal(root.left)

 

二叉搜索树的最小绝对差(中序遍历)

二叉搜索树转化为有序数组(中序遍历)。

双指针

 二叉树的最近公共祖先

二叉搜索树的最近公共祖先(递归 前序遍历)

只有左右,没有中,所以不在乎遍历顺序。

二叉搜索树中的插入操作

在叶子节点插入即可。

 

 修剪二叉搜索树

将有序数组转换为二叉搜索树

把中间的节点作为根节点,区间划分定为左闭右闭

将一个按照升序排列的有序数组,转换为一棵高度平衡二叉搜索树。

 把二叉搜索树转换为累加树

 二叉树结束了!!!

未完待续,不定时更新

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值