文章目录
因为lz考研复试可能优先回溯 动态规划 双指针,所以lz先进行这三样了!!!
二叉树递归遍历
#include<iostream>
#include <vector>
using namespace std;
struct TreeNode{
int val;
TreeNode*left;
TreeNode*right;
TreeNode():val(0),left(nullptr),right(nullptr){}
TreeNode(int value):val(value),left(nullptr),right(nullptr){}
TreeNode(int value,TreeNode*left,TreeNode*right):val(value),left(left),right(right){}
};
class BinaryTree{
public:
// 先序遍历
void preorder(TreeNode*root,vector<int>&result){
if (!root)return;
result.push_back(root->val);
preorder(root->left,result);
preorder(root->right,result);
}
vector<int> preorderTraversal(TreeNode* root) {
vector<int>result;
preorder(root,result);
return result;
}
// 后续遍历
void postorder(TreeNode*root,vector<int>&result){
if(!root)return;
postorder(root->left,result);
postorder(root->right,result);
result.push_back(root->val);
}
vector<int> postorderTraversal(TreeNode* root) {
vector<int>result;
postorder(root,result);
return result;
}
//中序遍历
void in(TreeNode*root,vector<int>&result){
if(!root)return;
in(root->left,result);
result.push_back(root->val);
in(root->right,result);
}
vector<int> inorderTraversal(TreeNode* root) {
vector<int>result;
in(root,result);
return result;
}
};
int main(){
TreeNode*t4 = new TreeNode(7);
TreeNode*t3 = new TreeNode(8);
TreeNode*t2 = new TreeNode(3,t3, nullptr);
TreeNode*t1 = new TreeNode(1);
TreeNode*t0 = new TreeNode(5,t2,t4);
TreeNode*root = new TreeNode(10,t0,t1);
BinaryTree bt;
// 测试先序遍历
auto v = bt.preorderTraversal(root);
for (const auto &item: v) {
cout<< item <<endl;
}
delete root;
delete t0;
delete t1;
delete t2;
delete t3;
delete t4;
return 0;
}
二叉树迭代遍历
#include<iostream>
#include <vector>
#include<stack>
#include<algorithm>
using namespace std;
struct TreeNode{
int val;
TreeNode*left;
TreeNode*right;
TreeNode():val(0),left(nullptr),right(nullptr){}
TreeNode(int value):val(value),left(nullptr),right(nullptr){}
TreeNode(int value,TreeNode*left,TreeNode*right):val(value),left(left),right(right){}
};
class BinTree{
public:
// 先序遍历
/**
* 栈是先入后出 先序遍历是 中左右
* 入栈的时候先入右孩子 再入左孩子 这样出栈的时候可以先出左后出右
* */
vector<int> preorder(TreeNode*root){
vector<int>result;//保存遍历之后的结果
if (root== nullptr)return result;
stack < TreeNode * > st; // 模拟递归的栈
st.push(root);
while (!st.empty()){
auto r = st.top();
st.pop();
result.push_back(r->val);
if (r->right)st.push(r->right);
if (r->left)st.push(r->left);
}
return result;
}
// 后序遍历
/**
* 栈是先入后出 后序遍历是 左右中
* 我们可以按照先序的 不过入栈的时候先入左孩子 再入右孩子
* 这样的出来的是后序遍历的翻转
*/
vector<int>postorder(TreeNode*root){
stack<TreeNode*>st;
vector<int>result;
if (root== nullptr)return result;
st.push(root);
while (!st.empty()){
auto r = st.top();
st.pop();
result.push_back(r->val);
if (r->left)st.push(r->left);
if (r->right)st.push(r->right);
}
reverse(result.begin(),result.end());
return result;
}
//中序遍历
vector<int> inorder(TreeNode*root){
vector<int>result;
if (root== nullptr)return result;
TreeNode*cur = root;
stack<TreeNode*>st;
while (cur||!st.empty()){
if (cur){// 指针来访问节点,访问到最底层
st.push(cur);// 将访问的节点放进栈
cur=cur->left;
}else{
cur = st.top();// 从栈里弹出的数据,就是要处理的数据
st.pop();
result.push_back(cur->val);//中
cur=cur->right;//右
}
}
return result;
}
};
int main(){
TreeNode*t4 = new TreeNode(7);
TreeNode*t3 = new TreeNode(8);
TreeNode*t2 = new TreeNode(3,t3, nullptr);
TreeNode*t1 = new TreeNode(1);
TreeNode*t0 = new TreeNode(5,t2,t4);
TreeNode*root = new TreeNode(10,t0,t1);
BinTree bt;
auto v = bt.inorder(root);
for (const auto &item: v) {
cout<< item <<endl;
}
delete root;
delete t0;
delete t1;
delete t2;
delete t3;
delete t4;
return 0;
}
二叉统一的迭代遍历法
二叉树的层序遍历合集
二叉树层序遍历I
描述
给你一个二叉树,请你返回其按 层序遍历 得到的节点值。 (即逐层地,从左到右访问所有节点)。
题解
class Solution {
public:
vector<vector<int>> levelOrder(TreeNode* root) {
vector<vector<int>>result;
if(root==nullptr)return result;
queue<TreeNode*>q;
q.push(root);
while (!q.empty()){
vector<int>vec;
int size = q.size();
for (int i = 0; i < size; ++i) {
TreeNode* cur = q.front();
vec.push_back(cur->val);
q.pop();
if (cur->left)q.push(cur->left);
if (cur->right)q.push(cur->right);
}
result.push_back(vec);
}
return result;
}
};
二叉树层序遍历II
描述
给定一个二叉树,返回其节点值自底向上的层次遍历。 (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历)
题解
class Solution {
public:
vector<vector<int>> levelOrderBottom(TreeNode* root) {
vector<vector<int>>result;
if(root==nullptr)return result;
queue<TreeNode*>q;
q.push(root);
while (!q.empty()){
vector<int>vec;
int size = q.size();
for (int i = 0; i < size; ++i) {
TreeNode* cur = q.front();
vec.push_back(cur->val);
q.pop();
if (cur->left)q.push(cur->left);
if (cur->right)q.push(cur->right);
}
result.push_back(vec);
}
reverse(result.begin(),result.end());
return result;
}
};
二叉树的右视图
描述
给定一棵二叉树,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。
题解
层序遍历的时候,判断是否遍历到单层的最后面的元素,如果是,就放进result数组中,随后返回result就可以了。
class Solution {
public:
vector<int> rightSideView(TreeNode* root) {
vector<int>res;
if (root == nullptr)return res;
queue<TreeNode*>q;
q.push(root);
while (!q.empty()){
int len = q.size();
for (int i = 0; i < len; ++i) {
auto t = q.front();
q.pop();
if(i==len-1)res.push_back(t->val);
if (t->left)q.push(t->left);
if (t->right)q.push(t->right);
}
}
return res;
}
};
二叉树的层平均值
描述
给定一个非空二叉树, 返回一个由每层节点平均值组成的数组。
题解
本题就是层序遍历的时候把一层求个总和在取一个均值。
class Solution {
public:
vector<double> averageOfLevels(TreeNode* root) {
vector<double>res;
if (root== nullptr)return res;
queue<TreeNode*>q;
q.push(root);
while (!q.empty()){
const int len = q.size();
double count=0;
for (int i = 0; i < len; ++i) {
auto t = q.front();
q.pop();
count+=t->val;
if (t->left)q.push(t->left);
if (t->right)q.push(t->right);
}
res.push_back(count/len);
}
return res;
}
};
N叉树的层序遍历
描述
给定一个 N 叉树,返回其节点值的层序遍历。 (即从左到右,逐层遍历)。
题解
类似于二叉树的层序遍历
class Solution {
public:
vector<vector<int>> levelOrder(Node* root) {
vector<vector<int>>res;
if (root== nullptr)return res;
queue<Node*>q;
q.push(root);
while (!q.empty()){
vector<int>tmpRes;
int len = q.size();
for (int i = 0; i < len; ++i) {
auto t=q.front();
q.pop();
tmpRes.push_back(t->val);
for (int j = 0; j < t->children.size(); ++j)
q.push(t->children[j]);
}
res.push_back(tmpRes);
}
return res;
}
};
在每个树行中找最大值
描述
您需要在二叉树的每一行中找到最大的值。
题解
层序遍历,取每一层的最大值
class Solution {
public:
vector<int> largestValues(TreeNode* root) {
vector<int>res;
if (root== nullptr)return res;
queue<TreeNode*>q;
q.push(root);
while (!q.empty()){
int len = q.size();
int maxNum=-2147483648;
for (int i = 0; i < len; ++i) {
auto t=q.front();
q.pop();
maxNum=(t->val>maxNum)?t->val:maxNum;
if (t->left)q.push(t->left);
if (t->right)q.push(t->right);
}
res.push_back(maxNum);
}
return res;
}
};
填充每个节点的下一个右侧节点指针
描述
给定一个完美二叉树,其所有叶子节点都在同一层,每个父节点都有两个子节点。二叉树定义如下:
struct Node {
int val;
Node *left;
Node *right;
Node *next;
}
填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL。
初始状态下,所有 next 指针都被设置为 NULL。
题解
依旧是层序遍历,不过保存上次层序遍历的节点
class Solution {
public:
Node* connect(Node* root) {
if (root== nullptr)return root;
queue<Node*>q;
q.push(root);
while (!q.empty()){
int len = q.size();
Node*tmp= nullptr;
for (int i = 0; i < len; ++i) {
Node*t=q.front();
q.pop();
if (tmp)tmp->next=t;
if (i==len-1)t->next= nullptr;
else{
tmp=t;
}
if (t->left)q.push(t->left);
if (t->right)q.push(t->right);
}
}
return root;
}
};
填充每个节点的下一个右侧节点指针II
描述
给定一个二叉树:
struct Node {
int val;
Node *left;
Node *right;
Node *next;
}
填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL 。
初始状态下,所有 next 指针都被设置为 NULL 。
题解
一样的逻辑
class Solution {
public:
Node* connect(Node* root) {
if (root== nullptr)return root;
queue<Node*>q;
q.push(root);
while (!q.empty()){
int len = q.size();
Node*tmp= nullptr;
for (int i = 0; i < len; ++i) {
Node*t=q.front();
q.pop();
if (tmp)tmp->next=t;
if (i==len-1)t->next= nullptr;
else{
tmp=t;
}
if (t->left)q.push(t->left);
if (t->right)q.push(t->right);
}
}
return root;
}
};
二叉树最大深度
描述
给定一个二叉树,找出其最大深度。
二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。
说明: 叶子节点是指没有子节点的节点。
示例:
给定二叉树 [3,9,20,null,null,15,7],
题解:层序遍历
class Solution {
public:
int maxDepth(TreeNode*root){
if (root== nullptr)return 0;
queue<TreeNode*>q;
q.push(root);
int depth=0;
while (!q.empty()){
int len = q.size();
for (int i = 0; i < len; ++i) {
auto node=q.front();
q.pop();
if (node->left)q.push(node->left);
if (node->right)q.push(node->right);
}
++depth;
}
return depth;
}
};
题解:递归(深度优先搜索)
class Solution {
public:
int maxDepth(TreeNode* root) {
if (!root)return 0;
int leftHigh = maxDepth(root->left);
int rightHigh = maxDepth(root->right);
return max(leftHigh,rightHigh)+1;
}
};
二叉树的最小深度
描述
给定一个二叉树,找出其最小深度。
最小深度是从根节点到最近叶子节点的最短路径上的节点数量。
说明:叶子节点是指没有子节点的节点。
题解:层序遍历
只有当左右孩子都为空的时候,才说明遍历的最低点了。如果其中一个孩子为空则不是最低点
class Solution {
public:
int minDepth(TreeNode* root) {
if (root== nullptr)return 0;
queue<TreeNode*>q;
int depth=0;
q.push(root);
while (!q.empty()){
int len =q.size();
++depth;
for (int i = 0; i < len; ++i) {
TreeNode*node=q.front();
q.pop();
if (!node->left&&!node->right)return depth;
if (node->left)q.push(node->left);
if (node->right)q.push(node->right);
}
}
return depth;
}
};
题解:递归(深度优先)
class Solution {
public:
int minDepth(TreeNode *root) {
if (root == nullptr) {
return 0;
}
if (root->left == nullptr && root->right == nullptr) {
return 1;
}
int min_depth = INT_MAX;
if (root->left != nullptr) {
min_depth = min(minDepth(root->left), min_depth);
}
if (root->right != nullptr) {
min_depth = min(minDepth(root->right), min_depth);
}
return min_depth + 1;
}
};
翻转二叉树
描述
翻转一棵二叉树。
题解:递归法
本题使用递归法 很是方便,我们定义一个实现翻转的函数,但root有左/右孩子的时候再翻转其左右孩子,直至root的左右孩子为空
class Solution {
public:
void invert(TreeNode*root){
if (root== nullptr)return;
swap(root->left,root->right);
invert(root->left);
invert(root->right);
}
TreeNode* invertTree(TreeNode* root) {
invert(root);
return root;
}
};
题解:迭代法
前序遍历和后续遍历途中进行翻转,下面的代码使用的是前序遍历
class Solution {
public:
TreeNode*invertTree(TreeNode*root){
if (root== nullptr)return root;
stack<TreeNode*>st;
st.push(root);
while (!st.empty()){
auto node=st.top();
st.pop();
swap(node->left,node->right);
if (node->right)st.push(node->right);
if (node->left)st.push(node->left);
}
return root;
}
};
题解:层序遍历
class Solution {
public:
TreeNode*invertTree(TreeNode*root){
if (root== nullptr)return root;
queue<TreeNode*>q;
q.push(root);
while (!q.empty()){
auto node=q.front();
q.pop();
swap(node->left,node->right);
if (node->left)q.push(node->left);
if (node->right)q.push(node->right);
}
return root;
}
};
对称二叉树
描述
给定一个二叉树,检查它是否是镜像对称的。
题解:递归
class Solution {
public:
bool compare(TreeNode*left,TreeNode*right){
if (left&&!right)return false;
else if(!left&&right)return false;
else if (!left&&!right)return true;
else if(left->val!=right->val)return false;
bool leftFlag = compare(left->left,right->right);
bool rightFlag = compare(left->right,right->left);
return leftFlag&&rightFlag;
}
bool isSymmetric(TreeNode* root) {
if (!root)return true;
return compare(root->left,root->right);
}
};
题解:迭代法
class Solution {
public:
bool isSymmetric(TreeNode*root) {
if (!root)return true;
queue<TreeNode*>q;
q.push(root->left);
q.push(root->right);
while (!q.empty()){
auto n1=q.front();q.pop();
auto n2=q.front();q.pop();
if (!n1&&!n2)continue;
if (n1&&!n2||!n1&&n2||n1->val!=n2->val)return false;
q.push(n1->left);
q.push(n2->right);
q.push(n1->right);
q.push(n2->left);
}
return true;
}
};