LC958二叉树的完全性校验
/**
* 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:
bool isCompleteTree(TreeNode* root) {
if(root == nullptr) return true;
bool flag = false;
queue<TreeNode*> q;
q.push(root);
while(!q.empty()){
TreeNode *t = q.front();q.pop();
if(t == nullptr){
flag = true;
continue;
}
if(flag) return false;
//走到这个if说明此次循环没有t!=nullptr,而上次循环t==nullptr,
//所以说明有空节点夹杂在非空结点之前。
q.push(t->left);
q.push(t->right);
}
return true;
}
};
103.蛇形二叉树遍历
算法题:给定一棵二叉树,返回蛇形遍历顺序。leetcode水题,宽度优先遍历之后将偶数行的结果reverse就可以。只做出这一个。
#include<bits/stdc++.h>
using namespace std;
struct TreeNode{
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x): val(x), left(NULL), right(NULL){};
};
TreeNode* init(int *a, int len){
TreeNode *root = nullptr;
TreeNode *p = nullptr;
int flag = 0;
for(int i=0;i<len;){
if(i == 0) {
root = new TreeNode(a[i++]);
p = root;
cout<<p->val<<"mmm"<<endl;
}else{
cout<<a[i]<<"mmm"<<endl;
if(a[i] == NULL) p->left=nullptr;
else p->left = new TreeNode(a[i]);
i++;
cout<<a[i]<<"mmm"<<endl;
if(a[i] == NULL) p->right=nullptr;
else p->right = new TreeNode(a[i]);
i++;
if(flag == 0) {
if(p->left) p = p->left;
flag=1;
}else if(flag == 1){
if(p->right) p = p->right;
flag = 0;
}
}
}
return root;
}
void levelOrder(TreeNode *root){
TreeNode *p = root;
queue<TreeNode*> q;
q.push(root);
vector<vector<int>> v;
int level = 1;
while(!q.empty()){
int size = q.size();
vector<int>t;
for(int i=0;i<size;i++){
p = q.front();q.pop();
t.push_back(p->val);
if(p->left) q.push(p->left);
if(p->right) q.push(p->right);
}
if(level %2 == 0) reverse(t.begin(),t.end());
v.push_back(t);
level++;
}
for(int i=0;i<v.size();i++){
for(vector<int>::iterator it = v[i].begin(); it != v[i].end(); it++){
cout<<*it<<",";
}
cout<<endl;
}
}
int main(){
int a[] = {3,9,20,NULL,NULL,15,7};
int len = sizeof(a)/sizeof(a[0]);
TreeNode *root = init(a, len);
levelOrder(root);
}
00.二叉树遍历
#include<bits/stdc++.h>
using namespace std;
struct TreeNode{
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x):val(x),left(NULL),right(NULL){}
};
void PreOrder(TreeNode *root){
if(root == NULL) return ;
TreeNode *p = root;
cout<<p->val<<" ";
PreOrder(p->left);
PreOrder(p->right);
}
//层序非递归是一个队列
//前序非递归是一个栈
void PreOrder2(TreeNode *root){
if(root == NULL) return;
TreeNode *p = root;
stack<TreeNode *>s;
while(p || !s.empty()){
while(p){
cout<<p->val<<" ";
s.push(p);
p = p->left;
}
if(!s.empty()){
p = s.top(); s.pop();
p = p->right;
}
}
}
void InOrder(TreeNode *root){
if(root == NULL) return ;
InOrder(root->left);
cout<<root->val<<" ";
InOrder(root->right);
}
void InOrder2(TreeNode *root){
if(root == NULL) return;
TreeNode *p = root;
stack<TreeNode *> s;
while(p || !s.empty()){
while(p){
s.push(p);
p = p->left;
}
if(!s.empty()){
p = s.top();
s.pop();
cout<<p->val<<" ";
p = p->right;
}
}
}
void PostOrder(TreeNode *root){
if(root == NULL) return ;
PostOrder(root->left);
PostOrder(root->right);
cout<<root->val<<" ";
}
void postorder(TreeNode *root) {
stack<TreeNode*> s;
TreeNode* pre=NULL;
TreeNode* cur;
s.push(root);
while(!s.empty()) {
cur = s.top();
if ((cur->left==NULL && cur->right==NULL) ||
(pre!=NULL&&(pre==cur->left||pre==cur->right))) {
cout << cur->val << " ";
pre = cur;
s.pop();
}
if (cur->right) s.push(cur->right);
if (cur->left) s.push(cur->left);
}
}
//后序遍历非递归1:由前序非递归改进,采用根右左的遍历写法,最后结果再翻转
void PostOrder1(TreeNode *root){
vector<TreeNode*> v;
stack<TreeNode*>s;
TreeNode *p = root;
while(p || !s.empty()){
while(p){
v.push_back(p);
s.push(p);
p=p->right;
}
if(!s.empty()){
p = s.top();s.pop();
p = p->left;
}
}
reverse(v.begin(),v.end());
for(int i=0;i<v.size();i++){
cout<<v[i]->val<<" ";
}
}
//后序遍历非递归2:建立一个指向前一节点的指针,标记右孩子是否被访问
void PostOrder2(TreeNode *root){
TreeNode *pre = NULL;
TreeNode *p = root;
stack<TreeNode*>s;
while(p || !s.empty()){
while(p){
s.push(p);
p = p->left;
}
p = s.top();//这里先不要弹出栈顶,因为可能右子树还要进来,如果有右子树要进来则这个相对根节点就需要稍后再弹出
if(p->right == pre || p->right == NULL){ //若没有右节点或者右节点已经被访问过则输出这个相对根节点
s.pop();
cout<<p->val<<" ";
pre = p;
p = NULL;
}else{
p = p->right;
}
}
}
void LevelOrder(TreeNode *root){
queue<TreeNode*> q;
q.push(root);
TreeNode *p = root;
while(!q.empty()){
p = q.front();
q.pop();
cout<<p->val<<" ";
if(p->left) q.push(p->left);
if(p->right) q.push(p->right);
}
}
TreeNode* init(TreeNode *root){
TreeNode *p = root;
fstream f("int.txt");
int x;
while(f>>x){
if(p->left == NULL){
p->left = new TreeNode(x);
}else{
p->right = new TreeNode(x);
p = p->left;
}
}
return root;
}
int main(){
TreeNode root(0);
init(&root);
cout<<"前序:"<<" ";
PreOrder(&root);
cout<<"\n前序:"<<" ";
PreOrder2(&root);
cout<<"\n中序: " <<" ";
InOrder(&root);
cout<<"\n中序: " <<" ";
InOrder2(&root);
cout<<"\n后序: " <<" ";
PostOrder(&root);
cout<<endl;
PostOrder1(&root);
cout<<endl;
PostOrder2(&root);
cout<<"\n层序:"<<" ";
LevelOrder(&root);
}
// 0
// 1 2
// 3 4
// 5 6
//7 8
//9
07.重建二叉树(给前中写后序)
输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
例如,给出
前序遍历 preorder = [3,9,20,15,7] 中序遍历 inorder = [9,3,15,20,7]
返回如下的二叉树:
3
/ \
9 20
/ \
15 7
/**
* 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* buildTree(vector<int>& preorder, vector<int>& inorder) {
//递归分治
return recursionBuild(preorder.begin(),preorder.end(),inorder.begin(),inorder.end());
}
//递归分治
TreeNode* recursionBuild(vector<int>::iterator preBegin, vector<int>::iterator preEnd,vector<int>::iterator inBegin, vector<int>::iterator inEnd )
{
if(inEnd==inBegin) return NULL;
TreeNode* cur = new TreeNode(*preBegin);
auto root = find(inBegin,inEnd,*preBegin);
cur->left = recursionBuild(preBegin+1,preBegin+1+(root-inBegin),inBegin,root);
cur->right = recursionBuild(preBegin+1+(root-inBegin),preEnd,root+1,inEnd);
return cur;
}
};
感想:迭代器迭代器迭代器
26.树的子结构
输入两棵二叉树A和B,判断B是不是A的子结构。(约定空树不是任意一个树的子结构)
B是A的子结构, 即 A中有出现和B相同的结构和节点值。
/**
* 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:
bool isSubStructure(TreeNode* A, TreeNode* B) {
if(A==NULL|| B==NULL) return false;
bool res = false;
if(A->val == B->val){
res = helper(A,B);
}
if(!res){
res = isSubStructure(A->left,B);
}
if(!res){
res = isSubStructure(A->right,B);
}
return res;
}
bool helper(TreeNode* a,TreeNode* b){
if(b==NULL) return true;
if(a==NULL) return false;
if(a->val == b->val) return helper(a->left,b->left) && helper(a->right,b->right);
else return false;
}
};
感想:递归敢于截止。
28. 对称的二叉树
class Solution {
public:
bool isSymmetric(TreeNode* root) {
if(root == NULL) return true;
else return helper(root->left,root->right);
}
bool helper(TreeNode* leftRoot,TreeNode* rightRoot){
if(leftRoot == NULL && rightRoot == NULL) return true;
else if(leftRoot == NULL || rightRoot == NULL) return false;
if(leftRoot->val != rightRoot->val) return false;
else return helper(leftRoot->left,rightRoot->right) && helper(leftRoot->right,rightRoot->left);
}
};
32-3 从上到下打印二叉树
class Solution {
public:
vector<vector<int>> v;
vector<vector<int>> levelOrder(TreeNode* root) {
dfs(root,0);
return v;
}
void dfs(TreeNode* root,int level){
if(root == NULL) return ;
if(level>=v.size()) v.emplace_back(vector<int>());
v[level].emplace_back(root->val);
if(root->left) dfs(root->left,level+1);
if(root->right) dfs(root->right,level+1);
}
};
33.二叉搜索树树后序遍历序列
bool fun2(vector<int> &a,int left,int right){
if(left >= right) return true;
int pos = left;
for(;pos<right;pos++){
if(a[pos]>a[right]) break;
}
for(int j=pos;j<right;j++){
if(a[j]<a[right]) return false;
}
return fun2(a,left,pos-1) && fun2(a,pos,right-1);
}
void fun1(vector<int> &a){
fun2(a,0,a.size()-1);
}
34.二叉树中和为某一值的路径
输入一棵二叉树和一个整数,打印出二叉树中节点值的和为输入整数的所有路径。从树的根节点开始往下一直到叶节点所经过的节点形成一条路径。
示例:
给定如下二叉树,以及目标和 sum = 22,
5
/ \
4 8
/ / \
11 13 4
/ \ / \
7 2 5 1
返回:
[
[5,4,11,2],
[5,8,4,5]
]
class Solution {
public:
vector<vector<int>> v;
vector<int> single;
vector<vector<int>> pathSum(TreeNode* root, int sum) {
if(root == NULL) return v;
dfs(root,sum);
return v;
}
void dfs(TreeNode* root,int sum){
if(root == NULL) return;
sum -= root->val;
single.push_back(root->val);
if(!root->left && !root->right && sum == 0) v.emplace_back(single);
dfs(root->left,sum);
dfs(root->right,sum);
single.pop_back();
}
};
感想:想成了每次怎么新建一个vector实际上每一条dfs深度里都是一条新的vector,即使用的全局变量。
68-1 二叉搜索树中的最近祖先
/**
* 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) {
if(root->val < p->val && root->val < q->val) return lowestCommonAncestor(root->right, p, q);
if(root->val > p->val && root->val > q->val) return lowestCommonAncestor(root->left, p, q);
return root;
}
};
//迭代
class Solution {
public:
TreeNode* lowestCommonAncestor(TreeNode *root, TreeNode *p, TreeNode *q) {
while(root != NULL) {
if(root->val < p->val && root->val < q->val) // p,q 都在 root 的右子树中
root = root->right; // 遍历至右子节点
else if(root->val > p->val && root->val > q->val) // p,q 都在 root 的左子树中
root = root->left; // 遍历至左子节点
else break;
}
return root;
}
};
68-2二叉树中的最近公共祖先
TreeNode* fun1(TreeNode *root,TreeNode *p,TreeNode *q){
if(root == NULL) return NULL;
if(root->val == p->val || root->val == q->val) return root;
TreeNode *left = fun1(root->left,p,q);
TreeNode *right = fun1(root->right,p,q);
if(left == NULL && right == NULL) return NULL;
if(left == NULL) return right;
if(right == NULL) return left;
return root;
}
18.删除指定节点
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* deleteNode(ListNode* head, int val) {
ListNode* p = head;
ListNode* q = p;
if(p->val == val){
head = head->next;
return head;
}
while(p->next){
q=p;
p=p->next;
if(p->val == val){
if(p->next) q->next = p->next;
else q->next = NULL;
break;
}
}
return head;
}
};
55.二叉树深度
/**************************BFS*************************/
class Solution {
public:
int length=0;
queue<TreeNode*> q;
int maxDepth(TreeNode* root) {
if(root == NULL) return 0;
q.push(root);
while(!q.empty()){
int size = q.size();
for(int i=0;i<size;i++){
TreeNode* tmp = q.front();q.pop();
//注意这个出队操作是写在横排for的里面的,就是说同一行的节点的出队操作值归为length加一次。
if(tmp->left) q.push(tmp->left);
if(tmp->right) q.push(tmp->right);
}
length+=1;
}
return length;
}
};
/****************DFS**************************/
class Solution {
public:
int maxDepth(TreeNode* root) {
if(root == NULL) return 0;
return max(maxDepth(root->left),maxDepth(root->right))+1;
}
};