目录
一、144.二叉树的前序遍历
1.题目要求
给你二叉树的根节点 root
,返回它节点值的 前序 遍历。
示例 1:
输入:root = [1,null,2,3] 输出:[1,2,3]
2.解题思路
前序遍历:“中”、“左”、“右”。深度优先搜索,设计递归函数。
- 触底反弹:如果传入的根节点是NULL,此时直接return
- 超级操作:①先保存“中”节点的值②前序遍历以“左”为根节点③前序遍历以“右”为根节点
3.代码实现(递归思想)
/**
* 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:
void traversal(TreeNode* root,vector<int>& result){//递归函数
//前序遍历:中、左、右
//终止条件:根节点为NULL了,就返回
if(root == NULL)//触底反弹
return;
//超级操作:每次保存根节点的值,然后对左右节点继续进行前序遍历
result.push_back(root->val);
traversal(root->left,result);
traversal(root->right,result);
}
vector<int> preorderTraversal(TreeNode* root) {
vector<int> result;//定义结果集数组
traversal(root,result);
//返回结果集
return result;
}
};
4.代码实现(迭代思想)
/**
* 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:
//迭代法完成前序遍历
//利用栈的特性。弹出一个节点,然后先保存节点的值,再分别将右孩子左孩子push进去(push前先判断是否为NULL)
vector<int> preorderTraversal(TreeNode* root) {
stack<TreeNode*> st;
vector<int> result;
if(root == NULL)//不要忘记判断一下root是否为空
return result;
st.push(root);
while(!st.empty()){
TreeNode* node = st.top();
st.pop();
//弹出来,然后存放val,然后将右节点和左节点push进去(如果有右节点和左节点)
result.push_back(node->val);
if(node->right) st.push(node->right);//将右节点push进去
if(node->left) st.push(node->left);
}
return result;
}
};
二、145.二叉树的后序遍历
1.题目描述
给你一棵二叉树的根节点 root
,返回其节点值的 后序遍历 。
示例 1:
输入:root = [1,null,2,3] 输出:[3,2,1]
2.解题思路
后序遍历:“左”、“右”、“中”。深度优先搜索,设计递归函数。
- 触底反弹:如果传入的根节点是NULL,此时直接return
- 超级操作:①后序遍历以“左”为根节点②后序遍历以“右”为根节点③保存“中”节点的值
3.代码实现(递归思想)
/**
* 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:
void traversal(TreeNode* root,vector<int>& result){
//后序遍历:左、右、中
//触底反弹:传入的root节点是NULL,直接return
//超级操作:先分别后序遍历左、右,然后保存中节点的值
if(root == NULL)
return;//触底反弹(终止条件)
traversal(root->left,result);
traversal(root->right,result);
result.push_back(root->val);
}
vector<int> postorderTraversal(TreeNode* root) {
vector<int> result;
traversal(root,result);
return result;
}
};
4.代码实现(迭代思想)
/**
* 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:
//迭代法-后序遍历
//和前序遍历的迭代法 很接近
vector<int> postorderTraversal(TreeNode* root) {
stack<TreeNode*> st;
vector<int> result;
if(root == NULL) return result;//不要忘记加这一行
st.push(root);
while(!st.empty()){
TreeNode* node = st.top();
st.pop();
result.push_back(node->val);
if(node->left) st.push(node->left);
if(node->right) st.push(node->right);
}
//现在result是中右左,reverse一下就变成了左右中
reverse(result.begin(),result.end());
return result;
}
};
三、94.二叉树的中序遍历
1.题目描述
给定一个二叉树的根节点 root
,返回 它的 中序 遍历 。
示例 1:
输入:root = [1,null,2,3] 输出:[1,3,2]
2.解题思路
中序遍历:“左”、“中”、“右”。深度优先搜索,设计递归函数。
- 触底反弹:如果传入的根节点是NULL,此时直接return
- 超级操作:①中序遍历以“左”为根节点②保存“中”节点的值③中序遍历以“右”为根节点
3.代码实现(递归思想)
/**
* 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:
void traversal(TreeNode* root,vector<int>& result){
//中序遍历:左、中、右
//触底反弹:root为NULL,直接return
//超级操作 :1.中序遍历以左为根节点,2.保存中节点的值 3.中序遍历以右为根节点
if(root == NULL)
return;
traversal(root->left,result);
result.push_back(root->val);
traversal(root->right,result);
}
vector<int> inorderTraversal(TreeNode* root) {
vector<int> result;
traversal(root,result);
return result;
}
};
4.代码实现(迭代思想)
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root) {
vector<int> result;
stack<TreeNode*> st;
TreeNode* cur = root;
while (cur != NULL || !st.empty()) {
if (cur != NULL) { // 指针来访问节点,访问到最底层
st.push(cur); // 将访问的节点放进栈
cur = cur->left; // 左
} else {
cur = st.top(); // 从栈里弹出的数据,就是要处理的数据(放进result数组里的数据)
st.pop();
result.push_back(cur->val); // 中
cur = cur->right; // 右
}
}
return result;
}
};
四、11.盛最多水的容器
1.题目描述
给定一个长度为 n
的整数数组 height
。有 n
条垂线,第 i
条线的两个端点是 (i, 0)
和 (i, height[i])
。
找出其中的两条线,使得它们与 x
轴共同构成的容器可以容纳最多的水。
返回容器可以储存的最大水量。
说明:你不能倾斜容器。
2.解题思路
双指针法,left指向数组开头,right指向数组末尾。然后让双指针不断靠近,这意味着 容器的底是在不断缩小的,只有想办法让高变得更大才可以获取更大的容量。
3.代码实现(双指针法)
class Solution {
public:
int maxArea(vector<int>& height) {
int left = 0,right = height.size() - 1;//定义双指针
int result = 0;//用来存放最大水量
//每次移动指向较小的高的指针
for(;left < right;){
//先计算水量:底(right - left) * 高(较小的元素)
int smaller = height[left] < height[right] ? height[left] : height[right];//取较小的高
result = (right - left) * smaller < result ? result : (right - left) * smaller;//取最大的容水量
//开始移动指针
if(height[left] < height[right])
left++;
else
right--;
}
return result;
}
};