迭代法,大家可以直接过,二刷有精力的时候 再去掌握迭代法。感觉自己精力实在有限,还是暂时不考虑迭代法了。玛德,实在是过于难了。
110.平衡二叉树 (递归)
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
int getHeight(TreeNode* node) {
if (node == NULL) {
return 0;
}
int leftHeight = getHeight(node->left);
if (leftHeight == -1) return -1;
int rightHeight = getHeight(node->right);
if (rightHeight == -1) return -1;
return abs(leftHeight - rightHeight) > 1 ? -1 : 1 + max(leftHeight, rightHeight);
}
bool isBalanced(TreeNode* root) {
return getHeight(root) == -1 ? false : true;
}
};
再一次涉及到,什么是高度,什么是深度,可以巩固一下。
现在发现,所谓的递归就是层层外包,领主的领主不是我的领主。我只给两个左右结点派活,最大深度多少。然后我再比较,给出结果。如果有一个已经不是平衡二叉树,那就没必要比较了。至于他们怎么解决,让他们自己再外包。确实挺好理解的。写代码的时候想 if (leftHeight == -1) return -1; if (rightHeight == -1) return -1;两行代码可不可以删了,因为我的思维是,如果不平衡二叉树,往上传递会一直不平衡。想了半天才意识到,不能删。因为虽然传递给上面会一直不平衡,但是如果两个都不平衡二叉树,一直往上比较,结果就平衡了。比如
1
/ \
2 2
/ \
3 3
/ \
4 4
错错得正了。所以还是得一有问题,直接打死。
题目链接/文章讲解/视频讲解:代码随想录
257. 二叉树的所有路径 (递归)
递归
- 递归函数参数以及返回值
- 确定递归终止条件
- 确定单层递归逻辑
这是大家第一次接触到回溯的过程, 我在视频里重点讲解了 本题为什么要有回溯,已经回溯的过程。
卧槽,只能说,确实本质上就是三个板斧,做了那么多回归。先把上面的图看一下就懂了一些,回溯我的第一感觉就是:“再探再报”,一直深入下去,找到一个,再找一个,再探再报。递归就很线性,附庸的附庸不是我的附庸。
如果对回溯 似懂非懂,没关系, 可以先有个印象。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
private:
void traversal(TreeNode*cur,vector<int>&path,vector<string>&result)
{
path.push_back(cur->val);
if(cur->left==nullptr&&cur->right==nullptr)
{
string sPath;
for (int i = 0; i < path.size() - 1; i++) { // 将path里记录的路径转为string格式
sPath += to_string(path[i]);
sPath += "->";
}
sPath += to_string(path[path.size() - 1]); // 记录最后一个节点(叶子节点)
result.push_back(sPath); // 收集一个路径
return;
}
if (cur->left) { // 左
traversal(cur->left, path, result);
path.pop_back(); // 回溯
}
if (cur->right) { // 右
traversal(cur->right, path, result);
path.pop_back(); // 回溯
}
}
public:
vector<string> binaryTreePaths(TreeNode* root) {
vector<string>result;
vector<int>path;
if(root==nullptr)return result;
traversal(root,path,result);
return result;
}
};
题目链接/文章讲解/视频讲解:代码随想录
404.左叶子之和 (递归)
其实本题有点文字游戏,搞清楚什么是左叶子,剩下的就是二叉树的基本操作。
其实这题感觉还挺不算难得,递归主要是传入什么,返回什么,中间运行什么。
题目链接/文章讲解/视频讲解:代码随想录
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
int sumOfLeftLeaves(TreeNode* root) {
if(root==nullptr)
return 0;
int leftValue=0;
if (root->left != NULL && root->left->left == NULL && root->left->right == NULL)
leftValue=root->left->val;
return leftValue+sumOfLeftLeaves(root->left)+sumOfLeftLeaves(root->right);
}
};
222.完全二叉树的节点个数(递归)
纯递归法还是比较简单的,只要知道左边多少个,右边多少个,再加上自身就好了。
需要了解,普通二叉树 怎么求,完全二叉树又怎么求
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
private:
int getNodesNum(TreeNode* cur) {
if (cur == NULL) return 0;
int leftNum = getNodesNum(cur->left); // 左
int rightNum = getNodesNum(cur->right); // 右
int treeNum = leftNum + rightNum + 1; // 中
return treeNum;
}
public:
int countNodes(TreeNode* root) {
return getNodesNum(root);
}
};
题目链接/文章讲解/视频讲解:代码随想录
层序遍历感觉最好理解,对于来说最好使用,就很直观。
class Solution {
public:
int countNodes(TreeNode* root) {
queue<TreeNode*> que;
if (root != NULL) que.push(root);
int result = 0;
while (!que.empty()) {
int size = que.size();
for (int i = 0; i < size; i++) {
TreeNode* node = que.front();
que.pop();
result++; // 记录节点数量
if (node->left) que.push(node->left);
if (node->right) que.push(node->right);
}
}
return result;
}
};
要记住完全二叉树长什么样,就是前面几层都填满了,就是完全二叉树。
然后就要利用完全二叉树的性质进行计算,满二叉树一定有子二叉树是完全二叉树
class Solution {
public:
int countNodes(TreeNode* root) {
if (root == nullptr) return 0;
TreeNode* left = root->left;
TreeNode* right = root->right;
int leftDepth = 0, rightDepth = 0; // 这里初始为0是有目的的,为了下面求指数方便
while (left) { // 求左子树深度
left = left->left;
leftDepth++;
}
while (right) { // 求右子树深度
right = right->right;
rightDepth++;
}
if (leftDepth == rightDepth) {
return (2 << leftDepth) - 1; // 注意(2<<1) 相当于2^2,所以leftDepth初始为0
}
return countNodes(root->left) + countNodes(root->right) + 1;
}
};
还算是比较简单,主要是通过比较左子树和右子树,来判断子树是不是满二叉树。左子树结点加上右子树结点+1(本身)求出结果。