文章目录
1.预备知识
1.1 二叉树定义
1.2 二叉树的构造
2.路径总和 II
2.1 题目描述
给你二叉树的根节点 root 和一个整数目标和 targetSum ,找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。
叶子节点 是指没有子节点的节点。
2.2 算法思路
2.3 C++实现
/**
* 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<vector<int>> pathSum(TreeNode* root, int targetSum) {
vector<vector<int>> result;
vector<int> path;
int path_value=0;
preorder(root,path_value,targetSum,path,result);
return result;
}
private:
void preorder(TreeNode* Node,int &path_value,int sum,vector<int> &path,vector<vector<int>> &result){
if(!Node){
return;
}
path_value+=Node->val;
path.push_back(Node->val);
if(path_value==sum&&Node->left==nullptr&&Node->right==nullptr){
result.push_back(path);
}
preorder(Node->left,path_value,sum,path,result);
preorder(Node->right,path_value,sum,path,result);
path_value-=Node->val;
path.pop_back();
}
};
3.二叉树的最近公共祖先
3.1 题目描述
给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。
百度百科中最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”
3.2 解题思路
3.3 C++实现
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
vector<TreeNode*> path;
vector<TreeNode*> node_p_path;
vector<TreeNode*> node_q_path;
int finish=0;
preorder(root,p,path,node_p_path,finish);
path.clear();
finish=0;
preorder(root,q,path,node_q_path,finish);
int path_length=0;
if(node_p_path.size()<node_q_path.size()){
path_length=node_p_path.size();
}
else{
path_length=node_q_path.size();
}
TreeNode* result=0;
for(int i=0;i<path_length;i++){
if(node_p_path[i]==node_q_path[i]){
result=node_p_path[i];
}
}
return result;
}
private:
void preorder(TreeNode* Node,TreeNode* search,vector<TreeNode*>& path,vector<TreeNode*>& result,int finish){
if(!Node||finish==1){
return;
}
path.push_back(Node);
if(Node==search){
finish=1;
result=path;
}
preorder(Node->left,search,path,result,finish);
preorder(Node->right,search,path,result,finish);
path.pop_back();
}
};
4.二叉树展开为链表
4.1 题目描述
给你二叉树的根结点 root ,请你将它展开为一个单链表:
展开后的单链表应该同样使用 TreeNode ,其中 right 子指针指向链表中下一个结点,而左子指针始终为 null 。
展开后的单链表应该与二叉树 先序遍历 顺序相同。
4.2 思考
4.3 C++实现
/**
* 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 flatten(TreeNode* root) {
vector<TreeNode*> node_vec;
preorder(root,node_vec);
for(int i=1;i<node_vec.size();i++){
node_vec[i-1]->left=nullptr;
node_vec[i-1]->right=node_vec[i];
}
}
private:
void preorder(TreeNode* Node,vector<TreeNode*> &node_vec){
if(!Node){
return;
}
node_vec.push_back(Node);
preorder(Node->left,node_vec);
preorder(Node->right,node_vec);
}
};
4.4 解法二
4.5 C++实现
/**
* 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 flatten(TreeNode* root) {
TreeNode* last=nullptr;
preorder(root,last);
}
private:
void preorder(TreeNode* Node,TreeNode* &last){
if(!Node){
return;
}
if(!Node->left&&!Node->right){
last=Node;
return;
}
TreeNode* left=Node->left;
TreeNode* right=Node->right;
TreeNode* left_last=nullptr;
TreeNode* right_last=nullptr;
if(left){
preorder(left,left_last);
Node->left=nullptr;
Node->right=left;
last=left_last;
}
if(right){
preorder(right,right_last);
if(left_last){
left_last->right=right;
}
last=right_last;
}
}
};
5.二叉树的右视图
5.1 预备知识
#include <iostream>
#include<queue>
using namespace std;
struct TreeNode {
int val;
TreeNode* left;
TreeNode* right;
TreeNode(int x):val(x),left(NULL),right(NULL){}
};
void BFS_print(TreeNode* root) {
queue<TreeNode*> Q;
Q.push(root);
while (Q.size()) {
TreeNode* node = Q.front();
Q.pop();
cout << node->val << endl;
if (node->left) {
Q.push(node->left);
}
if (node->right) {
Q.push(node->right);
}
}
}
int main()
{
TreeNode tree1(1);
TreeNode tree2(11);
TreeNode tree3(9);
TreeNode tree4(3);
TreeNode tree5(0);
TreeNode tree6(2);
TreeNode tree7(8);
tree1.left = &tree2;
tree1.right = &tree3;
tree2.left = &tree4;
tree2.right = &tree5;
tree3.left = &tree6;
tree3.right = &tree7;
BFS_print(&tree1);
return 0;
}
5.2 题目描述
给定一棵二叉树,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。
5.3 解题思路
5.4 C++实现
/**
* 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> rightSideView(TreeNode* root) {
vector<int> view;
queue<pair<TreeNode*,int>> Q;
if(root){
Q.push(make_pair(root,0));
}
while(!Q.empty()){
TreeNode *node=Q.front().first;
int depth=Q.front().second;
Q.pop();
if(depth==view.size()){
view.push_back(node->val);
}
else{
view[depth]=node->val;
}
if(node->left){
Q.push(make_pair(node->left,depth+1));
}
if(node->right){
Q.push(make_pair(node->right,depth+1));
}
}
return view;
}
};
6. 课程表
6.1 预备知识
6.1.1 什么是图?
6.1.2 图的表示
6.1.3 图的深度优先遍历
6.1.4 图的宽度优先遍历
6.2 题目描述
你这个学期必须选修 numCourses 门课程,记为 0 到 numCourses - 1 。
在选修某些课程之前需要一些先修课程。 先修课程按数组 prerequisites 给出,其中 prerequisites[i] = [ai, bi] ,表示如果要学习课程 ai 则 必须 先学习课程 bi 。
例如,先修课程对 [0, 1] 表示:想要学习课程 0 ,你需要先完成课程 1 。
请你判断是否可能完成所有课程的学习?如果可以,返回 true ;否则,返回 false 。
6.3 分析
6.4 C++代码实现
struct GraphNode{
int label;
vector<GraphNode*> neighbors;
GraphNode(int x):label(x){};
};
class Solution {
public:
bool canFinish(int numCourses, vector<vector<int>>& prerequisites) {
vector<GraphNode*> graph;
vector<int> degree;
for(int i=0;i<numCourses;i++){
graph.push_back(new GraphNode(i));
degree.push_back(0);
}
for(int i=0;i<prerequisites.size();i++){
GraphNode* begin=graph[prerequisites[i][1]];
GraphNode* end=graph[prerequisites[i][0]];
begin->neighbors.push_back(end);
degree[prerequisites[i][0]]++;
}
queue<GraphNode*> Q;
for(int i=0;i<numCourses;i++){
if(degree[i]==0){
Q.push(graph[i]);
}
}
while(!Q.empty()){
GraphNode* node=Q.front();
Q.pop();
for(int i=0;i<node->neighbors.size();i++){
degree[node->neighbors[i]->label]--;
if(degree[node->neighbors[i]->label]==0){
Q.push(node->neighbors[i]);
}
}
}
for(int i=0;i<numCourses;i++){
delete graph[i];
}
for(int i=0;i<degree.size();i++){
if(degree[i]){
return false;
}
}
return true;
}
};