给定一个二叉树,它的每个结点都存放一个 0-9 的数字,每条从根到叶子节点的路径都代表一个数字。
例如,从根到叶子节点路径 1->2->3 代表数字 123。
计算从根到叶子节点生成的所有数字之和。
说明: 叶子节点是指没有子节点的节点。
链接:https://leetcode-cn.com/problems/sum-root-to-leaf-numbers
/*基本思想:递归的基本思想
*/
/**
* 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:
int del(TreeNode* root,int sum)
{
if(root == NULL) return 0;
sum = sum * 10 + root->val;
if(root->left == NULL && root->right == NULL) return sum;
return del(root->left, sum) + del(root->right, sum);
}
int sumNumbers(TreeNode* root) {
return del(root,0);
}
};
给定一个二叉树和一个目标和,判断该树中是否存在根节点到叶子节点的路径,这条路径上所有节点值相加等于目标和。
说明: 叶子节点是指没有子节点的节点。
链接:https://leetcode-cn.com/problems/path-sum/
/*基本思想:左右别求和 有一方ture即为true
*/
/**
* 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 del(TreeNode* root,int sum ,int target)
{
if(root == NULL)
return false;
sum+=root->val;
if(sum == target && root->left == NULL && root->right==NULL)
return true;
return del(root->left,sum,target) || del(root->right,sum,target);
}
bool hasPathSum(TreeNode* root, int sum) {
return del(root,0,sum);
}
};
给定一个二叉树和一个目标和,找到所有从根节点到叶子节点路径总和等于给定目标和的路径。
说明: 叶子节点是指没有子节点的节点。
链接:https://leetcode-cn.com/problems/path-sum-ii/
/*基本思想:回溯的基本思想,注意当到达叶子节点时,满足条件等于target需要返回上一层,进行sum和cur的操作,不满足条件也需要返回上一层,每次都是深度遍历,找到叶子
*/
/**
* 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:
void del(TreeNode* root,int sum ,int target,vector<int> &cur,vector<vector<int>> &res)
{
sum+=root->val;
cur.push_back(root->val);
if(sum == target && root->left==NULL && root->right == NULL )
{
res.push_back(cur);
sum-=root->val;
cur.pop_back();
}
else
{
if(root->left!=NULL)
del(root->left,sum,target,cur,res);
if(root->right!=NULL)
del(root->right,sum,target,cur,res);
sum-=root->val;
cur.pop_back();
}
}
vector<vector<int>> pathSum(TreeNode* root, int sum) {
vector<int> cur;
vector<vector<int>> res;
if(root == NULL)
return res;
del(root,0,sum,cur,res);
return res;
}
};
给定一个二叉树,判断它是否是高度平衡的二叉树。
本题中,一棵高度平衡二叉树定义为:
一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过1。
链接:https://leetcode-cn.com/problems/balanced-binary-tree/
/*基本思想,先递归计算某个节点的左右子树的高度,差值大于1 返回false
计算子树高度的时候,以他的左右子树最大的为该子树的高度
*/
/**
* 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:
int high(TreeNode* root)
{
if (root == NULL)
return 0;
int left_high = high(root->left)+1;
int right_high = high(root->right)+1;
return max(left_high,right_high);
}
bool isBalanced(TreeNode* root) {
if(root==NULL)
return true;
if(abs(high(root->left) - high(root->right)) > 1)
return false;
return isBalanced(root->left) && isBalanced(root->right);
}
};
给定两个二叉树,编写一个函数来检验它们是否相同。
如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。
链接:https://leetcode-cn.com/problems/same-tree/
/*基本思想:当节点不为空 就判断两个节点值相同的情况下,递归判断两个节点的左右子树是否都相同,不相等,返回false
当节点都为空,返回TRUE
否则返回false
*/
/**
* 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 isSameTree(TreeNode* p, TreeNode* q) {
if(p!=NULL && q!=NULL)
{
if(q->val==p->val)
return isSameTree(p->left,q->left) && isSameTree(p->right,q->right);
else
return false;
}
if(p==NULL && q==NULL)
return true;
return false;
}
};
给定一个二叉树,检查它是否是镜像对称的。
链接:https://leetcode-cn.com/problems/symmetric-tree/
/*基本思想:判断左子树的左节点等于右子树的右节点,左子树的右节点等于右子树的左节点,即为对称二叉树
所以判断一个树,传递他的左子树和右子树
可以用递归和迭代两种方法:迭代的时候要借助栈,每次将两种情况都放进去栈中只要栈不为空就一直判断
*/
/**
* 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 del(TreeNode*L , TreeNode*R)
{
if(R!=NULL && L!=NULL)
{
if(R->val == L->val)
return del(L->left,R->right) && del(L->right,R->left);
else
return false;
}
if(R== NULL && L==NULL)
return true;
return false;
}
bool isSymmetric(TreeNode* root) {
if(root == NULL)
return true;
else
return del(root->left,root->right);
}
*/
bool isSymmetric(TreeNode* root) {
if(!root) return true; //空树是对称的
stack<TreeNode *> s;
TreeNode *L=root->left,*R=root->right;
s.push(L);
s.push(R); //即使是空节点,也是可以push到栈里的,栈并不为空。
while(!s.empty())
{
L=s.top();
s.pop();
R=s.top();
s.pop();
if(!L && !R) continue; //L、R都是空节点
if(!L || !R) return false; //有一个为空,不对称
if(L->val!=R->val) return false; //值不相等,不对称
s.push(L->left);
s.push(R->right);
s.push(L->right);
s.push(R->left);
}
return true;
}
};
给定一个二叉树,判断其是否是一个有效的二叉搜索树。
假设一个二叉搜索树具有如下特征:
节点的左子树只包含小于当前节点的数。
节点的右子树只包含大于当前节点的数。
所有左子树和右子树自身必须也是二叉搜索树。
链接:https://leetcode-cn.com/problems/validate-binary-search-tree
/*基本思想:主要是设置上下界,对于左子树的节点,必须全部小于根节点,所以上界是根,对于右子树,必须所有节点大于根节点,所以下界是根
注意最小值和最大值int取到的情况,此处用long int避免
方法二:中序遍历。序列递增则为BST。
*/
/**
* 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 del(TreeNode * root , long int minval, long int maxval)
{
if(root==NULL)
return true;
if(root->val <= minval || root->val>=maxval)
return false;
return del(root->left,minval,root->val) && del(root->right,root->val,maxval);
}
bool isValidBST(TreeNode* root) {
return del(root,INT64_MIN,INT64_MAX);
}*/
vector<int> v;
void midTrav(TreeNode *root)
{
if(root==NULL)
return;
midTrav(root->left);
v.push_back(root->val);
midTrav(root->right);
}
bool isValidBST(TreeNode *root) {
if(root==NULL)
return true;
midTrav(root);
int len = v.size();
for(int i=0;i<len-1;i++)
{
if(v[i]>=v[i+1])
return false;
}
return true;
}
};
给定一个非空二叉树,返回其最大路径和。
本题中,路径被定义为一条从树中任意节点出发,达到任意节点的序列。该路径至少包含一个节点,且不一定经过根节点。
链接:https://leetcode-cn.com/problems/binary-tree-maximum-path-sum/
/*基本思想:求解的结果作为每次递归的中间值碰到大了就更新,对于中间节点作为当前节点作为根节点最大值是左子树的最大值+右子树的最大值,更新结果,但是函数的返回值应该只能返回左右子树中的最大的,因为从当前节点出发只能到达左右一边
*/
/**
* 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:
int maxvalue = INT_MIN;
int maxsum(TreeNode *root)
{
if(root == NULL)
return 0;
int leftsum = maxsum(root->left);
int rightsum = maxsum(root->right);
int sum = root->val;
//对于当前节点为根节点,他的和的最大值应该是加上左子树的最大值和右子树的最大值
if(leftsum>0)
sum += leftsum;
if(rightsum>0)
sum += rightsum;
if(sum>maxvalue)
maxvalue = sum;
return max(0,max(leftsum,rightsum)+root->val);//只能返回左右子树中较大值加上root.val,因为对于从根节点出发只能到达左右中的一个
}
int maxPathSum(TreeNode* root) {
if(root == NULL)
return 0;
maxsum(root);
return maxvalue;
}
};
给定一个二叉树,找到最长的路径,这个路径中的每个节点具有相同值。 这条路径可以经过也可以不经过根节点。
注意:两个节点之间的路径长度由它们之间的边数表示。
链接:https://leetcode-cn.com/problems/longest-univalue-path/
/*基本思想: 每个节点当作根节点计算最大值=左最大+右最大,中间用maxres纪录,但是返回应该是左右中的一个
*/
/**
* 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:
int maxres = 0;
int findmax(TreeNode* root)
{
if(!root) return 0;
int left = 0;
int right = 0;
left = findmax(root->left);
right = findmax(root->right);
if(root->left && root->right){
if(root->val == root->left->val && root->val == root->right ->val){
maxres =max(maxres, 2 + left + right);
return max(1+left, 1+right) ;
}
}
if (root->left && root->val == root->left->val )
{
maxres = max(maxres, 1+left);
return left+1;
}
if( root->right && root->val == root->right->val)
{
maxres = max(maxres, 1+right );
return 1+right ;
}
return 0;
}
int longestUnivaluePath(TreeNode* root) {
if(root == NULL)
return 0;
findmax(root);
return maxres;
}
};
给定一个二叉树,找出其最大深度。
二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。
说明: 叶子节点是指没有子节点的节点。
链接:https://leetcode-cn.com/problems/maximum-depth-of-binary-tree/
/*基本思想:基本的递归,左右分别递归求最大
*/
/**
* Definition for binary tree
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
int maxDepth(TreeNode *root) {
if(root == NULL)
return 0;
int left_depth = maxDepth(root->left);
int right_depth = maxDepth(root->right);
return max(left_depth,right_depth)+1;
}
};
给定一个二叉树,找出其最小深度。
最小深度是从根节点到最近叶子节点的最短路径上的节点数量。
说明: 叶子节点是指没有子节点的节点。
链接:https://leetcode-cn.com/problems/minimum-depth-of-binary-tree/
/*基本思路: 递归判断左右最小的,如果左右都有,则取最小的加上本节点,否则只有左子树,就左子树的结果加上本节点,否则就是右子树的结果加上本节点
*/
/**
* 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:
int minDepth(TreeNode* root) {
if(root==NULL)
return 0;
if(root->left && root->right)
return 1+(min(minDepth(root->left),minDepth(root->right)));
if(root->left)
return 1+minDepth(root->left);
if(root->right)
return 1+minDepth(root->right);
return 1;
}
};
给定一个二叉树,返回它的中序 遍历。
链接:https://leetcode-cn.com/problems/binary-tree-inorder-traversal/
/*基本思想:递归和迭代,迭代使用栈辅助实现,先一直把左子树进栈,之后找右子树
*/
/**
* 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:
/*
void inorder(TreeNode* root , vector<int> &r)
{
if(root == NULL)
return;
inorder(root->left,r);
r.push_back(root->val);
inorder(root->right,r);
}
vector<int> inorderTraversal(TreeNode* root) {
vector<int> r;
inorder(root,r);
return r;
}
*/
vector<int> inorderTraversal(TreeNode *root)
{
stack<TreeNode*> s;
vector<int> r;
TreeNode *t = root;
while(t || !s.empty() )
{
while(t!= NULL)
{
s.push(t);
t = t->left;
}
if(!s.empty()){
r.push_back(s.top()->val);
t = s.top()->right;
s.pop();
}
}
return r;
}
};
给定一个二叉树,返回它的 前序 遍历。
链接:https://leetcode-cn.com/problems/binary-tree-preorder-traversal/
/*基本思想:递归和迭代,迭代利用栈,每次放入root->val之后,先放root->right,然后再放root->left,这样出栈就是先出左,再出右
*/
/**
* 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:
/*
void preorder(TreeNode *root, vector<int> &res)
{
if(root == NULL)
{
return ;
}
res.push_back(root->val);
preorder(root->left,res);
preorder(root->right,res);
}
vector<int> preorderTraversal(TreeNode* root) {
vector<int> res;
preorder(root,res);
return res;
} */
vector<int> preorderTraversal(TreeNode* root)
{
stack<TreeNode*> s;
vector<int> res;
if(root==NULL)
return res;
s.push(root);
while(!s.empty())
{
TreeNode* t = s.top();
s.pop();
res.push_back(t->val);
if(t->right)
s.push(t->right);
if(t->left)
s.push(t->left);
}
return res;
}
};
给定一个二叉树,返回它的 后序 遍历。
链接:https://leetcode-cn.com/problems/binary-tree-postorder-traversal/
/*基本思想:递归和迭代,迭代可以仿照前序遍历,只需要最后反转一下就可以了
*/
/**
* 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:
/*
void postorder(TreeNode* root, vector<int> & res)
{
if(root == NULL)
return ;
postorder(root->left,res);
postorder(root->right,res);
res.push_back(root->val);
}
vector<int> postorderTraversal(TreeNode* root) {
vector<int> res;
postorder(root,res);
return res;
}
*/
vector<int> postorderTraversal(TreeNode* root) {
stack<TreeNode*> s;
vector<int> res;
if(root == NULL)
return res;
s.push(root);
while(!s.empty())
{
TreeNode* tmp = s.top();
res.push_back(tmp->val);
s.pop();
if(tmp->left)
s.push(tmp->left);
if(tmp->right)
s.push(tmp->right);
}
reverse(res.begin(),res.end());
return res;
}
};
给定一个单链表,其中的元素按升序排序,将其转换为高度平衡的二叉搜索树。
本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1。
链接:https://leetcode-cn.com/problems/convert-sorted-list-to-binary-search-tree
/*基本思想:对于链表首先要找到中点,找到中点后,要以中点的值建立一个数的根节点,然后需要把原链表断开,分为前后两个链表,都不能包含原中节点,然后再分别对这两个链表递归调用原函数,分别连上左右子节点即可。
*/
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
/**
* 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* ListToBST(ListNode* head, ListNode *tail) {
if (head == tail)
return NULL;
ListNode * fast = head;
ListNode * low =head;
while(fast!=tail && fast->next!=tail )
{
fast = fast->next->next;
low = low->next;
}
TreeNode *root,*lchild,*rchild;
root = new TreeNode(low->val);
root->left = ListToBST(head,low);
root->right = ListToBST(low->next,tail);
return root;
}
TreeNode* sortedListToBST(ListNode* head) {
return ListToBST(head,NULL);
}
};
给定一个二叉树,返回其按层次遍历的节点值。 (即逐层地,从左到右访问所有节点)。
链接:https://leetcode-cn.com/problems/binary-tree-level-order-traversal/
/*
基本思想:利用队列来实现,每次取队头,然后把他的左孩子和右孩子都放入队列,用一个队列记录他们所在的层数,在同一层,就放入同一个vector
不在同一层,先把之前的vector放入结果,然后再重新放入vector
*/
/**
* 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:
vector<vector<int>> levelOrder(TreeNode* root) {
vector<vector<int>> res;
queue<TreeNode*> q;
queue<int> num;
if(root == NULL)
return res;
q.push(root);
num.push(1);
int preindex = 1;
vector<int> cur;
while(!q.empty())
{
TreeNode *t = q.front();
int index = num.front();
if(index == preindex)
{
cur.push_back(t->val);
}
else
{
res.push_back(cur);
cur.clear();
cur.push_back(t->val);
}
q.pop();
num.pop();
if(t->left!=NULL)
{
q.push(t->left);
num.push(index+1);
}
if(t->right!=NULL)
{
q.push(t->right);
num.push(index+1);
}
preindex = index;
}
res.push_back(cur);
return res;
}
};
给定一个整数 n,求以 1 ... n 为节点组成的二叉搜索树有多少种?
链接:https://leetcode-cn.com/problems/unique-binary-search-trees/
/*基本思想: 动态规划,对于1到n的数字,dp[n]可以选择任何一个数字作为根,当选择k为根的时候,二叉搜索树的数量为左子树的数量*右子树的数量
左子树都是比k小的,所以数量就是dp[k-1] ,右子树都是比k大的,所以数量为dp[n-k]
所以对于每一个k累加就是n对应的数量
设dp[i]表示共有i个节点时,能产生的BST树的个数
i == 0 时,空树的个数必然为1,因此dp[0] = 1
i == 1 时,只有1这个根节点,数量也为1,因此dp[1] = 1
i == 2 时, dp[2] = dp[0] * dp[1] + dp[1] * dp[0]
dp[n]= k为1-n所有情况累加: dp[k-1]*dp[n-k]
以此类推
*/
class Solution {
public:
int numTrees(int n) {
int dp[n+1];
dp[0]=1;
dp[1]=1;
for(int i=2;i<=n;i++)
{
dp[i]=0;
for(int j=1; j<=i;j++)
{
dp[i] += dp[j-1]*dp[i-j];
}
}
return dp[n];
}
};
给定一个整数 n,生成所有由 1 ... n 为节点所组成的二叉搜索树。
链接:https://leetcode-cn.com/problems/unique-binary-search-trees-ii/
/*基本思路:每次一次选取一个结点为根,然后递归求解左右子树的所有结果,最后根据左右子树的返回的所有子树,依次选取然后接上(每个左边的子树跟所有右边的子树匹配,而每个右边的子树也要跟所有的左边子树匹配,总共有左右子树数量的乘积种情况),构造好之后作为当前树的结果返回
/**
* 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:
vector<TreeNode*> tree( int start,int end)
{
vector<TreeNode*> res;
if(start>end)
{
res.push_back(NULL);
return res;
}
for(int i=start;i<=end;i++) //以i为根节点的树,其左子树由[1, i-1]构成, 其右子树由[i+1, n]构成。该原则建树具有唯一性
{
vector<TreeNode*> left_res = tree(start,i-1);
vector<TreeNode*> right_res = tree(i+1,end);
//每个左边的子树跟所有右边的子树匹配,而每个右边的子树也要跟所有的左边子树匹配,总共有左右子树数量的乘积种情况
int lsize = left_res.size();
int rsize = right_res.size();
for(int j=0;j<lsize;j++){
for(int k=0;k<rsize;k++){
TreeNode *root = new TreeNode(i);
root->left = left_res[j];
root->right = right_res[k];
res.push_back(root);
}
}
}
return res;
}
vector<TreeNode*> generateTrees(int n) {
vector<TreeNode*> res;
if(n==0)
return res;
return tree(1,n);
}
};
二叉搜索树中的两个节点被错误地交换。
请在不改变其结构的情况下,恢复这棵树。
链接:https://leetcode-cn.com/problems/recover-binary-search-tree/
/*基本思想:中序遍历的应用:记录三个指针:pre表示前一个数,first表示第一个要交换的,second表示第二个要交换的
根据二叉搜索树的性质,对于root,pre指向他的前一个节点,一定要比他小,当比他大的时候,证明这个pre出错,所以first就是该pre
然后当确定了first之后,root之后的一定是比他大的,所以对于要交换的位置,一定是root之后比他小的,否则就是root。递归寻找最小的root。
然后遍历之后交换first和second即可
方法二:先中序遍历存储,然后排序,最后填树
*/
/**
* 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:
void Inorder(TreeNode *root,vector<int> &vec,vector<TreeNode *> &node)
{
if(!root)
return;
Inorder(root->left,vec,node);
vec.push_back(root->val);
node.push_back(root);
Inorder(root->right,vec,node);
}
void recoverTree(TreeNode *root)
{
vector<int> vec;
vector<TreeNode *> node;
Inorder(root,vec,node);
sort(vec.begin(),vec.end());
for(int i=0;i<vec.size();i++)
node[i]->val = vec[i];
}/*
TreeNode *pre=new TreeNode(INT_MIN);
TreeNode *first=NULL;
TreeNode *second=NULL;
void inorder(TreeNode *root)
{
if(root == NULL)
return;
inorder(root->left);
if(first == NULL && pre->val > root->val)
first = pre;
if(first != NULL && pre->val > root->val) //
second = root;
pre= root;
inorder(root->right);
}
void recoverTree(TreeNode* root) {
if(root==NULL)
return ;
inorder(root);
swap(first->val,second->val);
}*/
};
将一个按照升序排列的有序数组,转换为一棵高度平衡二叉搜索树。
本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1。
链接:https://leetcode-cn.com/problems/convert-sorted-array-to-binary-search-tree/
/*基本思想:二分法,根据二叉搜索树的特点,对于有序数组,就是中点为根,左右是他的左右子树,递归构造就好
*/
/**
* 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* BST(vector<int>& nums, int start,int end)
{
if(start>=end)
return NULL;
int m =(start+end)/2;
TreeNode *root =new TreeNode(nums[m]);
root->left = BST(nums,start,m);
root->right = BST(nums,m+1,end);
return root;
}
TreeNode* sortedArrayToBST(vector<int>& nums) {
TreeNode* root;
root = BST(nums,0,nums.size());
return root;
}
};
根据一棵树的前序遍历与中序遍历构造二叉树。
注意:
你可以假设树中没有重复的元素。
链接:https://leetcode-cn.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/
/*基本思想:递归,根据前序遍历和中序遍历的特点,分别找到左子树和右子树的前序和中序递归就好*/
/**
* 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) {
if(preorder.size() ==0 || inorder.size()==0)
return NULL;
TreeNode *root = new TreeNode(preorder[0]);
vector<int> lpre,rpre,lin,rin;
int j=1;
int i;
for(i=0;i<inorder.size();i++)
{
if(inorder[i]==preorder[0])
break;
lpre.push_back(preorder[j++]);
lin.push_back(inorder[i]);
}
for(i=i+1;i<inorder.size();i++)
{
rin.push_back(inorder[i]);
rpre.push_back(preorder[j++]);
}
root->left = buildTree(lpre,lin);
root->right = buildTree(rpre,rin);
return root;
}
};
根据一棵树的中序遍历与后序遍历构造二叉树。
注意:
你可以假设树中没有重复的元素。
链接:https://leetcode-cn.com/problems/construct-binary-tree-from-inorder-and-postorder-traversal/
/*基本思想:递归,和前序思想一样,只不过后序遍历的根是最后一个,根据构建规则分别找到左右子树的中序和后序递归就好
*/
/**
* 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>& inorder, vector<int>& postorder) {
if(inorder.size()==0 || postorder.size()==0)
return NULL;
int len = postorder.size();
TreeNode *root = new TreeNode(postorder[len-1]);
int i;
vector<int> lin;
vector<int> rin;
vector<int> lpost;
vector<int> rpost;
int j=0;
for(i=0;i<inorder.size();i++)
{
if(inorder[i] == postorder[len-1])
break;
lin.push_back(inorder[i]);
lpost.push_back(postorder[j++]);
}
for(i=i+1;i<inorder.size();i++)
{
rin.push_back(inorder[i]);
rpost.push_back(postorder[j++]);
}
root->left = buildTree(lin,lpost);
root->right = buildTree(rin,rpost);
return root;
}
};
给定一个二叉树,返回其节点值的锯齿形层次遍历。(即先从左往右,再从右往左进行下一层遍历,以此类推,层与层之间交替进行)。
链接:https://leetcode-cn.com/problems/binary-tree-zigzag-level-order-traversal/
/*基本思想:相当于层次遍历,每次一层存入到一个vector,然后两个放节点的vector,第一个遍历存值,存孩子节点到第二个vector,然后用第二个vector替换第一个,继续找孩子,直到没有孩子结束为止,最后对偶数行进行反转输出就好(注意偶数行对应下标是奇数)
*/
/**
* 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:
vector<vector<int>> zigzagLevelOrder(TreeNode* root) {
vector<TreeNode*> r1;
r1.push_back(root);
vector<TreeNode*> r2;
vector<vector<int>> res;
vector<int> cur;
if(root==NULL)
return res;
while(r1.size()!=0)
{
for(int i=0;i<r1.size();i++)
{
cur.push_back(r1[i]->val);
if(r1[i]->left !=NULL)
r2.push_back(r1[i]->left);
if(r1[i]->right !=NULL)
r2.push_back(r1[i]->right);
}
r1 = r2;
r2.clear();
res.push_back(cur);
cur.clear();
}
for(int i=0;i<res.size();i++)
{
if(i%2!=0)
reverse(res[i].begin(),res[i].end());
}
return res;
}
};
给定一个二叉树,原地将它展开为链表。
链接:https://leetcode-cn.com/problems/flatten-binary-tree-to-linked-list/
/*基本思想:递归,先把左右子树都捋直,然后把左子树移动到节点的右子树上,最后把原来的右子树接到后面,注意接的时候要找到最后一个节点去接
*/
/**
* 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:
void flatten(TreeNode* root) {
if(root == NULL)
return ;
//先把左右子树捋直
flatten(root->left);
flatten(root->right);
TreeNode* tmp;
tmp = root->right;
if(root->left){
root->right = root->left;
root->left = NULL;
while(root->right)
root = root->right;
root->right = tmp;
}
}
};
二叉树数据结构TreeNode可用来表示单向链表(其中left置空,right为下一个链表节点)。实现一个方法,把二叉搜索树转换为单向链表,要求值的顺序保持不变,转换操作应是原址的,也就是在原始的二叉搜索树上直接修改。
返回转换后的单向链表的头节点。
链接:https://leetcode-cn.com/problems/binode-lcci
/*基本思想:
方法一:中序遍历思想,新建一个树,按照中序遍历过程连接就好
方法二:先把左右分别排列好,然后连接,连接的时候注意要找到左和右的头各是什么,左的头是左子树最后的右孩子,右的头是右子树最后的左孩子,连接就好,注意将root的左设置为NULL
*/
/**
* 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:
void convert(TreeNode* root)
{
if(!root)
return ;
TreeNode* right = root->right;
while(right && right->left)
right = right->left;
convert(root->left);
convert(root->right);
TreeNode* left = root->left;
while(left && left->right)
left = left->right;
if(left){
left->left = NULL;
left->right = root;
}
if(right){
root->right = right;
}
root->left = NULL;
}
TreeNode *res = new TreeNode(0);
TreeNode *result = res;
void inorder(TreeNode* root)
{
if(!root)
return ;
inorder(root->left);
TreeNode*tmp = new TreeNode(root->val);
res->left = NULL;
res->right = tmp;
res = res->right;
inorder(root->right);
}
TreeNode* convertBiNode(TreeNode* root) {
if(!root)
return NULL;
TreeNode* head = root;
while(head->left)
head = head->left;
convert(root);
return head;
/*
inorder(root);
return result->right;
*/
}
};
给定一个二叉搜索树的根结点 root
,返回树中任意两节点的差的最小值。
链接:https://leetcode-cn.com/problems/minimum-distance-between-bst-nodes/
/*基本思想:
方法一: 利用中序遍历,根据二叉搜索树的特点,中序遍历是一个递增序列,所以求最小的节点差,就是判断相邻两个节点的差最小的,可以在中序遍历的过程中记录每个节点的前一个节点(全局变量记录),然后计算就好.
方法二: 也是计算找到前一个节点,总体递归思路是,对于一个节点,要比较他和左子树的差和他和右子树的差取最小,并且在他的左子树中找最小和右子树中找最小(递归)。注意比较他和左子树的差的时候,因为二叉搜索树的特点,所以要找到他的左子树的最后的右孩子才是他和左子树的差,同理,他和右子树的差,是他的右子树的最底的左孩子和他的差。
*/
/**
* 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* pre = NULL;
int min_value = INT_MAX;
void inorder(TreeNode * root )
{
if(!root)
return ;
inorder(root->left);
if(pre)
min_value = min(min_value, root->val - pre->val);
pre = root;
inorder(root->right);
}
int minDiffInBST(TreeNode* root) {
if(!root)
return 0;
inorder(root);
return min_value;
}
*/
int minDiffInBST(TreeNode* root) {
if(root->left == NULL && root->right == NULL)
return INT_MAX;
int left = INT_MAX;
int right = INT_MAX;
int leftmin = INT_MAX;
int rightmin = INT_MAX;
TreeNode *pre = NULL;
if(root->left){
pre = root->left;
while(pre->right)
pre = pre->right;
left = root->val - pre->val;
leftmin = minDiffInBST(root->left);
}
if(root->right){
pre = root->right;
while(pre->left)
{
pre = pre->left;
}
right = pre->val - root->val;
rightmin = minDiffInBST(root->right);
}
return min(min(left,right), min(leftmin,rightmin));
}
};