您的位置:首页 > 其它

树的相关题目

2015-10-30 23:45 344 查看

五.树

5.1二叉树的遍历 分别写出递归和迭代版本*

5.1.1.先序优先遍历 Binary Tree Preorder Traversal

递归版本
class Solution {
public:
vector<int> preorderTraversal(TreeNode *root) {
vector<int > ret;
helper(ret,root);
return ret;
}

void helper(vector<int>&ret , TreeNode* root){
if(root==NULL)return ;
else
ret.push_back(root->val);
if(root->left!=NULL)
helper(ret,root->left);
if(root->right!=NULL)
helper(ret,root->right);
}
};
迭代版本
class Solution {
public:
vector<int> preorderTraversal(TreeNode *root) {
//用栈来实现先序优先遍历
vector<int > ret;
if(root==NULL) return ret;
stack<TreeNode* > mystack;
mystack.push(root);
TreeNode* temp;
while(!mystack.empty()){
temp= mystack.top();
mystack.pop();

ret.push_back(temp->val); //先把右子节点入栈
if(temp->right!=NULL)
mystack.push(temp->right);
if(temp->left!= NULL)
mystack.push(temp->left);
}
return ret;
}
};

5.1.2中序优先遍历

递归版本
class Solution {
public:
vector<int> inorderTraversal(TreeNode *root) {
vector<int >  ret;
helper(ret, root);
return ret;
}
void helper(vector<int>&ret ,TreeNode* root){
if(root==NULL) return;
if(root->left!=NULL)
helper(ret,root->left);
ret.push_back(root->val);
if(root->right!=NULL)
helper(ret,root->right);
}
};
迭代版本
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root) {

vector<int> ret;
if(root==NULL) return ret;
stack<TreeNode* > mystack;
TreeNode* p=root;
while(p!=NULL){
mystack.push(p);
p=p->left;
}

while(!mystack.empty()){
TreeNode * temp = mystack.top();
mystack.pop();
ret.push_back(temp->val);
if(temp->right!=NULL){ //如果出栈的节点右子节点不空,这将右子节点的左子节点入入栈,直到没有左子节点
p=temp->right;
while(p!=NULL){
mystack.push(p);
p=p->left;
}
}
}
return ret;
}
};

5.1.3 后序优先遍历

思考步骤:1.3.注意

5.1.4 输出二叉树的每层的数。 leetcode 102

思考:递归版本,相当于广度优先遍历,用一个参数来表明大小步骤:1.3.注意
class Solution {
public:
vector<vector<int>> levelOrder(TreeNode* root) {
vector<vector<int> > ret;
if(root==NULL)
return ret;
helper(root, ret,0);
return ret;
}

void helper(TreeNode* root, vector<vector<int> > &ret,int level){

if(!root)return ;

if(level+1>ret.size() ) //注意 level>ret.size()-1    unsigned int 与 int 运算时, int 会被转换为unit
ret.push_back(vector<int>());
ret[level].push_back(root->val);

if(root->left!=NULL)
helper(root->left, ret ,level+1);
if(root->right!=NULL)
helper(root->right, ret,level+1);
}
};
class Solution {
public:
vector<vector<int> > levelOrder(TreeNode* root) {
vector<vector<int> > ret;
if(root==NULL)
return ret;
vector<TreeNode* >  layer;

layer.push_back(root);
while(!layer.empty()){
vector<int> temp;
vector<TreeNode* > deq;
TreeNode* t;
for(int i=0 ;i<layer.size();i++){
t= layer[i];
temp.push_back(t->val);
if(t->left)

154e4
deq.push_back(t->left);
if(t->right)
deq.push_back(t->right);
}
ret.push_back(temp);
layer=deq;
}
return ret;
}
};

class Solution {
public:
vector<vector<int> > levelOrder(TreeNode* root) {
vector<vector<int> > ret;
if(root==NULL)
return ret;
deque<TreeNode* > deq1;
deque<TreeNode* > deq2;

deq1.push_back(root);
while(!deq1.empty())
{
vector<int> temp;
TreeNode* t;
while(!deq1.empty()){
t=deq1.front();
deq1.pop_front();
temp.push_back(t->val);
if(t->left)
deq2.push_back(t->left);
if(t->right)
deq2.push_back(t->right);
}
ret.push_back(temp);
swap(deq1,deq2);  //这个知识交换指向的空间,并没有复制操作
}
return ret;
}
};

5.1.5 返回二叉树每层最右边的节点

结果同上:
//只不过是
//result[i]=root->val; 不断根新最后一个数存放的数组
class Solution {
public:
vector<int> rightSideView(TreeNode* root) {

vector<int> ret;
vector<TreeNode* > layer;
if(root==NULL) return ret;
layer.push_back(root);
int level=0;
while(!layer.empty()){
vector<TreeNode* > temp;
for(int i=0;i<layer.size();i++){
TreeNode*  p=layer[i];
if(level+1>ret.size())
ret.resize(level+1);
ret[level]=layer[i]->val;
if(p->left!=NULL)
temp.push_back(p->left);
if(p->right!=NULL)
temp.push_back(p->right);
}
layer=temp;
level++;
}
return ret;
}
};

5.2树的判定

5.2.1 两个树是否相等

思考:Given two binary trees, write a function to check if they are equal or not.Two binary trees are considered equal if they are structurally identical and the nodes have the same value.步骤:1.3.注意
class Solution {
/* 1.如果其中之一NULL,则该判断另一个子树是否为NULL
* 2.当前两值是否相等,递归判定其左右子树
*/
public:
bool isSameTree(TreeNode* p, TreeNode* q) {
if(p==NULL) return q==NULL;
if(q==NULL) return p==NULL;
return p->val==q->val&&isSameTree(p->left,q->left)&&isSameTree(p->right,q->right);
}
};

//非递归版本 借用栈来实现
class Solution {
public:
bool isSameTree(TreeNode* p, TreeNode* q) {

if(p==NULL)return q==NULL;
if(q==NULL) return p==NULL;
stack<TreeNode* > stk;
stk.push(q);
stk.push(p);

while(!stk.empty())
{
p=stk.top();
stk.pop();
q=stk.top();
stk.pop();
if(p==NULL&&q==NULL) continue;
if(p==NULL||q==NULL) return false;

if(p->val!=q->val) return false;
stk.push(q->right);
stk.push(p->right);
stk.push(q->left);
stk.push(p->left);
}

return true;
}
};

5.2.2 判断树是否对称

- **思考**:

- **步骤**:
* 1.
* 2.
*
*
*
* 3.
- **注意**:
class Solution {
public:
bool isSymmetric(TreeNode *root) {
if(root==NULL) return true;
return helper(root->left,root->right);
}
bool helper(TreeNode * p, TreeNode * q){
if(p==NULL) return q==NULL;
if(q==NULL)  return p==NULL;
return p->val==q->val&&helper(p->left,q->right)&&helper(p->right,q->left);
}
};

// 非递归版本
class Solution {
public:
bool isSymmetric(TreeNode* root) {
if(!root) return true;
return isSymmetric(root->left, root->right);
}
bool isSymmetric(TreeNode* p, TreeNode* q) {
if(!p&&!q) return true;

stack<TreeNode* > stk;
stk.push(q);
stk.push(p);
while(!stk.empty()){
p=stk.top();
stk.pop();
q=stk.top();
stk.pop();
if(!p&&!q) continue;
if(!p||!q) return false;
if(p->val!=q->val) return false;

stk.push(q->right);
stk.push(p->left);
stk.push(q->left);
stk.push(p->right);
}

return true;
}
};

5.2.3 二叉树是否平衡 Validate Binary Search Tree

Given a binary tree, determine if it is height-balanced.For this problem, a height-balanced binary tree is defined as a binary tree in which the depth of the two subtrees of every node never differ by more than 1.
class Solution {
public:
bool isBalanced(TreeNode *root) {

int height = getHeight(root);
if(height==-1)
return false;
return true;
}

int getHeight(TreeNode * root) {
if(root==NULL) return 0;

int left = getHeight(root->left);
int right =getHeight(root->right);

if(left==-1||right==-1||abs(left-right)>1) return -1;
return  max(left,right)+1;
}
};

5.2.4 二叉搜索树是否合法 Validate Binary Search Tree

Description :Given a binary tree, determine if it is a valid binary search tree (BST).Assume a BST is defined as follows:The left subtree of a node contains only nodes with keys less than the node’s key.The right subtree of a node contains only nodes with keys greater than the node’s key.Both the left and right subtrees must also be binary search trees.思考: 中序遍历,当前值大于中序遍历的last 值,全部成立即可,那么怎么获取中序遍历的最后一个之呢,使用引用
class Solution {
public:
bool isValidBST(TreeNode* root) {
if(root==NULL)
return true;
bool mark=true;
int last=0;
help(root,mark,last);
}
bool help(TreeNode* root, bool& first, int &last){
if(root==NULL) return true;

bool templeft = help(root->left,first,last);  // 遍历左子树,同时返回遍历的最后一个值

if(!templeft) return false;   // 左子树不合法,则返回false

if(first){                  // 当前节点是第一个值,这不比较
first=false;
} else if(last>=root->val)         // 不是第一个节点则比较
return false;

last = root->val;                //更新已遍历的最后一个值
return help(root->right,first,last); // 遍历右子树

}
};

5.3 树的路径与深度

5.3.1 二叉树的最小深度 letcode 111 Minimum Depth of Binary Tree

Description:Given a binary tree, find its minimum depth.The minimum depth is the number of nodes along the shortest path from the root node down to the nearest leaf node.思考:1.二叉树的广度优先遍历,利用队列,直到找到一个叶子节点,则停止循环。2.递归的解法: 只有叶子节点才算深度,如果为叶子节点,则返回1,如果非叶子节点,但其中左右子树为NULL,则返回另一个为空的子树的深度,若左右子树都不为NULL,则返回两者中小的+1;
class Solution {
public:
int minDepth(TreeNode* root) {

if(root==NULL) return 0;

if(root->left==NULL&&root->right==NULL) return 1;

if(root->left==NULL)return minDepth(root->right)+1;
if(root->right==NULL) return minDepth(root->left)+1;

return min(minDepth(root->left),minDepth(root->right))+1;

}
};

class Solution {
public:
int minDepth(TreeNode* root) {
if(root==NULL)return 0;
vector<TreeNode* > vec;
vec.push_back(root);
int ret=0;
while(!vec.empty()){
ret++;
vector<TreeNode* >temp;
for(int i=0;i<vec.size();i++){
if(vec[i]->left!=NULL)
temp.push_back(vec[i]->left);
if(vec[i]->right!=NULL)
temp.push_back(vec[i]->right);
if(vec[i]->left==NULL&&vec[i]->right==NULL)
return ret;
}
vec=temp;
}
return ret;
}
};

5.3.2 二叉树的最大高度 leetcode 104

class Solution {
public:
int maxDepth(TreeNode* root) {
if(root==NULL)return 0;
return max(maxDepth(root->left),maxDepth(root->right))+1;
}
};

5.3.3 是否存在和为定值的路径 leetcode 112

Description:Given a binary tree and a sum, determine if the tree has a root-to-leaf path such that adding up all the values along the path equals the given sum.For example:Given the below binary tree and sum = 22,5/ \4 8/ / \11 13 4/ \ \7 2 1return true, as there exist a root-to-leaf path 5->4->11->2 which sum is 22.
class Solution {
public:
bool hasPathSum(TreeNode *root, int sum) {

if(root==NULL) return false;
if(root->left==NULL&&root->right==NULL) {
if(sum==root->val)
return true;
else return false;
}
return hasPathSum(root->left,sum-root->val)||
hasPathSum(root->right,sum-root->val);
}

};

5.3.4 Binary Tree Maximum Path Sum leetcode 124

class Solution {
public:
int maxPathSum(TreeNode* root) {

if(root==NULL) return 0;
int  m=root->val;
getSum(root,m);
return m;
}

int getSum(TreeNode * root ,int &m){
if(root==NULL) return 0;

int left = getSum(root->left,m);
int right =getSum(root->right,m);

int ret =max(max(left ,right),0)+root->val;  //经过当前节点的长路径,左,右,仅有当前节点
m=max(max(ret,m),left+right+root->val);      // 横跨当前节点的最长路径

return ret;
}

};

5.4 树的构造与变换

5.4.1 Flatten Binary Tree to Linked List

实际上的先序遍历变为链表
class Solution {public:void flatten(TreeNode* root) {if(root==NULL) return ;stack<TreeNode* > stk;stk.push(root);TreeNode te(0);TreeNode* dummy=&te;TreeNode* tail=dummy;TreeNode * current;while(!stk.empty()){current =stk.top();stk.pop();if(current->right)stk.push(current->right);if(current->left)stk.push(current->left);tail->right=current;tail=current;tail->left =NULL;tail->right =NULL;}root=dummy->right;}};

5.4.2 Populating Next Right Pointers in Each Node

 - **思考**:1.立即想到使用广搜,记录每一层的链表尾节点,但需要有一个 vector<TreeLinkNode* >  来记录每一层的尾节点,不符合题目的常数空间的要求2. 递归调用,对每一层已经链接好的链表,遍历其中每个节点,操纵他们的子节点
步骤:1.3.注意
// 采用广度优先遍历的思想class Solution {public:void connect(TreeLinkNode *root) {vector<TreeLinkNode* > ret;helper(root, ret,0);}void helper(TreeLinkNode* root , vector<TreeLinkNode* > &ret, int level){if(root==NULL) return;if(level+1>ret.size())ret.push_back(root);else{ret[level]->next=root;ret[level]=root;}helper(root->left ,ret,level+1);helper(root->right, ret,level+1);}};
class Solution {public:void connect(TreeLinkNode *root) {if(root==NULL||root->left==NULL) return;TreeLinkNode* p=root;TreeLinkNode* tail=root->left;  //下一层链表的队尾while(p!=NULL){if(p==root){p->left->next =p->right;}else {tail->next=p->left;p->left->next =p->right;}tail =p->right;p=p->next;}connect(root->left);}};

5.4.3 Populating Next Right Pointers in Each Node II

class Solution {public:void connect(TreeLinkNode *root) {vector<TreeLinkNode* > ret;helper(root, ret,0);}void helper(TreeLinkNode* root , vector<TreeLinkNode* > &ret, int level){if(root==NULL) return;if(level+1>ret.size())ret.push_back(root);else{ret[level]->next=root;ret[level]=root;}helper(root->left ,ret,level+1);helper(root->right, ret,level+1);}};//递归版本class Solution {public:void connect(TreeLinkNode *root) {if(root==NULL) return;TreeLinkNode* p=root;TreeLinkNode temp(0);TreeLinkNode* tail=&temp;while(p!=NULL){if(p->left==NULL&&p->right==NULL){p=p->next;continue;}else if(p->left!=NULL&&p->right!=NULL){tail->next =p->left;p->left->next=p->right;tail=p->right;}else {tail->next = (p->left!=NULL)?p->left:p->right;tail=tail->next;}p=p->next;}connect(temp.next);}};//迭代版本class Solution {public:void connect(TreeLinkNode *root) {if(root==NULL) return;TreeLinkNode* p;// 迭代版本while(root!=NULL){TreeLinkNode temp(0);TreeLinkNode* tail=&temp;p=root;while(p!=NULL){if(p->left==NULL&&p->right==NULL){p=p->next;continue;}else if(p->left!=NULL&&p->right!=NULL){tail->next =p->left;p->left->next=p->right;tail=p->right;}else {tail->next = (p->left!=NULL)?p->left:p->right;tail=tail->next;}p=p->next;}root=temp.next;}}};

5.4.4 Binary Search Tree Iterator

维护一个结构从开头每次调用next,返回中序遍历下一个节点思考:用栈s保存每个根节点——一条路径cur表示当前要考虑的根节点cur 一直往左走,走过的节点入栈最后一个出栈(无左子树),访问它,它就是下一个要考虑的节点, cur = s.top()cur = cur->right;注意缓存,如果调用两次hasNext不应该改变结果个人思考: 实际上是中序遍历的迭代版本
/*** Definition for binary tree* struct TreeNode {*     int val;*     TreeNode *left;*     TreeNode *right;*     TreeNode(int x) : val(x), left(NULL), right(NULL) {}* };*/class BSTIterator {public:BSTIterator(TreeNode *root) {while(root!=NULL){mystack.push(root);root=root->left;}}/** @return whether we have a next smallest number */bool hasNext() {return !mystack.empty();}/** @return the next smallest number */int next() {TreeNode* temp=mystack.top();mystack.pop();TreeNode* p;if(temp->right!=NULL){p=temp->right;while(p!=NULL){mystack.push(p);p=p->left;}}return temp->val;}private :stack<TreeNode* > mystack;};/*** Your BSTIterator will be called like this:* BSTIterator i = BSTIterator(root);* while (i.hasNext()) cout << i.next();*/

5.4.5 Construct Binary Tree from Preorder and Inorder Traversal Leetcode 105

给定二叉树前、中序遍历,构造二叉树 (Leetcode 105)分析:前序遍历序列第一个是根节点x从中序遍历序列中找到根节点x中序遍历中x的左边序列对应等长的前序遍历序列左子树中序遍历中x的右边序列对应等长的前序遍历序列右子树
class Solution {public:TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {return helper(preorder,inorder,0,preorder.size()-1,0,inorder.size()-1);}TreeNode*  helper(vector<int>& preorder, vector<int>& inorder ,int pl,int ph ,int il,int ih){if(pl>ph) return NULL;TreeNode * root = new TreeNode(preorder[pl]);int i=il;for( ;i<=ih;i++){if(inorder[i]==preorder[pl])break;}int leftlen=i-il;int rightlen=ih-i;root->left = helper(preorder,inorder,pl+1,pl+leftlen,il,i-1);root->right =helper(preorder,inorder,pl+leftlen+1,ph,i+1,ih);return root;}};

5.4.6 Construct Binary Tree from Inorder and Postorder Traversal leetcode 106

定二叉树后、中序遍历,构造二叉树后序遍历序列最后一个是根节点x从中序遍历序列中找到根节点x中序遍历中x的左边序列对应等长的后序遍历序列左子树中序遍历中x的右边序列对应等长的后序遍历序列右子树
class Solution {public:TreeNode *buildTree(vector<int> &inorder, vector<int> &postorder) {if(inorder.size()==0)  return NULL;int N = inorder.size();TreeNode * ret= helper(inorder, postorder, 0,N-1 ,0,N-1)return ret;}TreeNode * helper(vector<int> &inorder, vector<int> &postorder, int instart ,int inend ,int postart,int poend) {if(instart==inend)  return new TreeNode(inorder[instart]);if(instart>inend)  return NULL;int last = postorder[poend];TreeNode * ret = new TreeNode(last);int mid=instart;for(int i=instart ;i<=inend ;i++)if(inorder[i]==last){mid= i;break;}ret->left= helper(inorder,postorder, instart,mid-1,postart,postart+(mid-1-instart));ret->right = helper(inorder,postorder, mid+1,inend,postart+(mid-1-instart)+1,poend-1);return ret;}};

5.4.7 Convert Sorted Array to Binary Search Tree leetcode108

Given an array where elements are sorted in ascending order, convert it to a height balanced BST.
class Solution {public:TreeNode* sortedArrayToBST(vector<int>& nums) {return  helper(nums,0,nums.size()-1);}TreeNode* helper(vector<int>& nums, int start,int end){if(start>end) return NULL;int mid =start+(end-start)/2;TreeNode* root=new TreeNode(nums[mid]);root->left=helper(nums,start,mid-1);root->right =helper(nums,mid+1,end);return root;}};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  二叉树 leetcode