二叉树的翻转
- 这道题应该是要用递归方法来做才好了,那么选择什么递归遍历方式呢?前序可以、后序可以但是中序不太行,因为会出现重复翻转的情况
- 翻转函数我们可以直接调用swap()函数进行实现
- 递归3部曲
对称二叉树
- 这道题需要用两个指针分别从根节点的左右两个方向去判断是否对称,一旦有遇到不对称的即为 非对称二叉树
- 对称二叉树的处理内容就是判断,判断某个节点能否与另一个节点对称;
- 可以用层序遍历,将每一层的节点收集到一个vector数组中并用双指针法判断其是否对称;可以用递归的方法,相当于判断根节点的左右两个子树是否是可以相互翻转的。
- 对于递归的方法而言,由于判断的逻辑是:判断根节点的左右两个子树是否可以翻转,才能判断出以根节点为跟的树是否是对称的,那么就有点自下而上的意思了,因此只能后序遍历。
二叉树的最大深度
方法一:层序遍历,很好做,只要统计二叉树遍历的层数即可得到最大深度。
方法二:深度优先即递归法,通常,求高度用后序遍历;求深度用的是前序遍历。
二叉树的最小深度
方法一:层序遍历,很好做,遇到左右孩子均为空的情况就返回层数即可。
方法二:深度优先递归法,求二叉树的最小深度和求二叉树的最大深度的差别主要在于处理左右孩子不为空的逻辑。
此处总结以下递归的思想:
以上面两题为例,对根节点而言,求最小深度就是要求最小的高度,要 求根节点的最大/最小高度,就要求左右子树的最大/最小高度,得到左右子树的最大/最小高度以后 + 1;然后要 求左子树的根节点的最大/最小高度,······,最终递归到了叶子节点:要得到叶子节点的高度就返回以叶子节点为根节点的树的最大/最小高度,因此终止条件就是遇到空节点时将返回0,然后在上一层+1;想明白这个处理逻辑以后,按照单层递归的逻辑去思考写好代码,其实程序就是会按着一层一层的去遍历。
完全二叉树的节点个数
方法一:层序遍历,这就和普通的二叉树求节点的方法没什么区别了!
方法二: 要注意到,完全二叉树中是包含了满二叉树的,(在完全二叉树中如何判断子树是满二叉树呢?方法为:(在完全二叉树中,向左递归的深度 = 向右递归的深度))。那么用后序遍历的方法求完全二叉树的节点数量,首先应该判断一个子树是否完全二叉树,并计算该完全二叉树的深度,若是,直接用公式计算该子树的节点数量,若不是则继续递归。
110.平衡二叉树
深度优先遍历递归法,处理的内容就是,分别计算节点的左右子树的高度,判断左右子树的高度差绝对值超不超过1(求高度用的是后序遍历),若不超过1,则返回该节点的最大高度;若超过1,那就不用再进行判断了,因为整颗树就已经是非平衡的二叉树,直接返回false就可以了!
贪心算法
贪心算法的整体思路就是通过局部最优推出全局最优。用直白的话来说就是指:想要完成整个任务,那就得一个一个来完成。
例如:分发饼干中,想要让尽可能多的孩子吃饱,那么就得让一个一个孩纸吃饱。如此产生的解题思路就是,优先用大尺寸的饼干先喂饱胃口大的孩子,一个一个饼干喂。
动态规划算法
怎么确定是动态规划的题目呢?
- 需要用到前面或者后面的状态去确定当前状态的值。
- 要善于举例子,从第一层、第二层开始思考,而不是宏观的将其数学式子列出来(动态规划就是利用子问题推导出总的问题的)。
动态规划解题5步曲:
- 确定dp数组以及下标的含义
- 确定递推公式
- dp数组如何初始化
- 确定遍历顺序
- 举例推导dp数组
动态规划解题思路总结:
C++语法基础
数组
定义一个n*n的二维数组
vector<vector<int>> res(n, vector<int>(n, 0));
// 使用vector定义一个二维数组
定义多个同类型的变量
int startx = 0, starty = 0;//注意中间是,号 不是分号;
将int型变量转换为string | 将string类型变量转换为int
int a = 0;
string sPath;
sPath += to_string(0);
//通过to_string将int型的a转换为string类型数据
return stoi(strNum); //利用stoi将strNum这个字符串转换为int型变量
左移和右移
左移:指数运算,例如:2 << 2 就相当于 2的2次方
右移:除运算,例如:2 >> 2 就相当于 2 / 2等于1。