100Same Tree46.4%Easy

非常简单

class Solution {
public:
    bool isSameTree(TreeNode* p, TreeNode* q) {
        if(p==NULL&&q==NULL) return true;
        else if(p&&!q||!p&&q) return false;
        if(p->val!=q->val) return false;
        else
        {
            return isSameTree(p->left,q->left)&&isSameTree(p->right,q->right);
        }
    }
};
较简单的写法:

bool isSameTree(TreeNode *p, TreeNode *q) {
    if (p == NULL || q == NULL) return (p == q);
    return (p->val == q->val && isSameTree(p->left, q->left) && isSameTree(p->right, q->right));
}

101 Symmetric Tree38.6%Easy 判断一个树是否是对称树 参考《剑》28 递归方法

Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its center).

For example, this binary tree [1,2,2,3,4,4,3] is symmetric:

    1
   / \
  2   2
 / \ / \
3  4 4  3

But the following [1,2,2,null,3,null,3] is not:

    1
   / \
  2   2
   \   \
   3    3

Note:
Bonus points if you could solve it both recursively and iteratively.

递归方法:

class Solution {
public:
    bool isSymmetric(TreeNode* root) {
        return isSymmetric(root,root);
    }
    bool isSymmetric(TreeNode*root1,TreeNode* root2){
        if(root1==NULL&&root2==NULL)
            return true;
        if(root1==NULL||root2==NULL)
            return false;
        if(root1->val!=root2->val)
            return false;
        return isSymmetric(root1->left,root2->right)&&isSymmetric(root1->right,root2->left);
    }
};
迭代方法:

思路是使用队列实现递归的原理.这个原理与宽度优先遍历使用栈是类似的。这个方法还需要练一遍

class Solution {
public:
    bool isSymmetric(TreeNode* root) {
        if(!root) return true;
        TreeNode* left,*right;
        queue<TreeNode*> qLeft,qRight;
        qLeft.push(root->left);
        qRight.push(root->right);
        while(!qLeft.empty()&&!qRight.empty())
        {
            left=qLeft.front();
            right=qRight.front();
            qLeft.pop();
            qRight.pop();
            if(left==NULL&&right==NULL)
                continue;
            if(left==NULL||right==NULL)
                 return false;
            if(left->val!=right->val)
                return false;
            qLeft.push(left->left);
            qLeft.push(left->right);
            qRight.push(right->right);
            qRight.push(right->left);
        }
        return true;  
    }
};


104 Maximum Depth of Binary Tree52.5%Easy 剑 55

Given a binary tree, find its maximum depth.

The maximum depth is the number of nodes along the longest path from the root node down to the farthest leaf node.

寻找二叉树的最大深度
思路当前树的深度等于其两棵子树深度的较大值
class Solution {
public:
    int maxDepth(TreeNode* root) {
        if(!root) return 0;
        int left=maxDepth(root->left);
        int right=maxDepth(root->right);
        return (left>right?left:right)+1;
    }
};

105 Construct Binary Tree from Preorder and Inorder Traversal32.1%Medium

Given preorder and inorder traversal of a tree, construct the binary tree.

递归方法:

class Solution {
public:
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
          int n=preorder.size();
        int m=inorder.size();
        if(n==0||m==0||n!=m) return NULL;
        return build(preorder,inorder,0,n-1,0,m-1);
    }
    TreeNode* build(vector<int>& preorder, vector<int>& inorder,int pf,int pr,int inf,int inr){
        int head;
        if(pr<pf||inr<inf) return NULL;
        for(int i=inf;i<=inr;i++)
        {
            if(preorder[pf]==inorder[i]) 
            {
                head=i;
                break;
            }
        }
        TreeNode* newNode=new TreeNode(preorder[pf]);
        if(pf==pr) return newNode;
        newNode->left=build(preorder,inorder,pf+1,head-inf+pf,inf,head-1);
        newNode->right=build(preorder,inorder,head-inf+pf+1,pr,head+1,inr);
        return newNode;
    }
};

还有迭代方法,没有练习:

/*I din't find iterative solutions discussed in the old Discuss. So, I thought, I will add my solution in here.

The idea is as follows:

Keep pushing the nodes from the preorder into a stack (and keep making the tree by adding nodes to the left of the previous node) until the top of the stack matches the inorder.

At this point, pop the top of the stack until the top does not equal inorder (keep a flag to note that you have made a pop).

Repeat 1 and 2 until preorder is empty. The key point is that whenever the flag is set, insert a node to the right and reset the flag.

*/
class Solution {
public:
    TreeNode *buildTree(vector<int> &preorder, vector<int> &inorder) {
        
        if(preorder.size()==0)
            return NULL;
        
        stack<int> s;
        stack<TreeNode *> st;
        TreeNode *t,*r,*root;
        int i,j,f;
        
        f=i=j=0;
        s.push(preorder[i]);
        
        root = new TreeNode(preorder[i]);
        st.push(root);
        t = root;
        i++;
        
        while(i<preorder.size())
        {
            if(!st.empty() && st.top()->val==inorder[j])
            {
                t = st.top();
                st.pop();
                s.pop();
                f = 1;
                j++;
            }
            else
            {
                if(f==0)
                {
                    s.push(preorder[i]);
                    t -> left = new TreeNode(preorder[i]);
                    t = t -> left;
                    st.push(t);
                    i++;
                }
                else 
                {
                    f = 0;
                    s.push(preorder[i]);
                    t -> right = new TreeNode(preorder[i]);
                    t = t -> right;
                    st.push(t);
                    i++;
                }
            }
        }
        
        return root;
    }
};

106 Construct Binary Tree from Inorder and Postorder Traversal 32.0% Medium
递归方法:
class Solution {
public:
    TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
        //中序遍历和后序遍历
        //后序遍历的最后一个节点是根节点
        //在中序遍历中找到这个节点
        //中序遍历序列中节点左边的是左子树,在后序遍历中从起始位置相对的片段是左子树的节点
        int n=inorder.size();
        int m=postorder.size();
        if(n==0||m==0||n!=m) return NULL;
        return build(inorder,postorder,0,n-1,0,m-1);
    }
    TreeNode* build(vector<int>& inorder, vector<int>& postorder,int pf,int pr,int inf,int inr){
        int head;
        if(pr<pf||inr<inf) return NULL;
        for(int i=pf;i<=pr;i++)
        {
            if(inorder[i]==postorder[inr]) 
            {
                head=i;//找到中序遍历
                break;
            }
        }
        TreeNode* newNode=new TreeNode(postorder[inr]);
        if(pf==pr) return newNode;
        newNode->left=build(inorder,postorder,pf,head-1,inf,inf+head-pf-1);
        newNode->right=build(inorder,postorder,head+1,pr,inf+head-pf,inr-1);
        return newNode;
    }
};
 

别人的方法: 迭代 

108 Convert Sorted Array to Binary Search Tree42.0%Easy

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) {
        int n=nums.size();
        if(n==0) return nullptr;
        TreeNode* res=new TreeNode(nums[n/2]);
        int first=0,last=n-1;
        res->left=sortedArrayToBST(nums,first,n/2-1);
        res->right=sortedArrayToBST(nums,n/2+1,last);
        return res;
    }
    TreeNode* sortedArrayToBST(vector<int>&nums,int first,int last){
        if(first>last) return nullptr;
        int middle=(first+last)/2;
        TreeNode* res=new TreeNode(nums[middle]);
        if(first==last) return res;
        res->left=sortedArrayToBST(nums,first,middle-1);
        res->right=sortedArrayToBST(nums,middle+1,last);
        return res;
    }
};

110 Balanced Binary Tree37.3%Easy

判断一个树是否是平衡二叉树

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.

看的答案

方法1:复杂度是O(N^2),自顶向上

class Solution {
public:
    int length(TreeNode* root){
        if(!root) return 0;
        return max(length(root->left),length(root->right))+1;
    }
    bool isBalanced(TreeNode* root) {
        if(!root) return true;
        int left=length(root->left);
        int right=length(root->right);
        return abs(left-right)<=1&&isBalanced(root->left)&&isBalanced(root->right);
  //不仅要判断当前树是否是平衡的还要判断他的子树也是平衡的
        
    }
};

方法2:使用DFS,自底向上 再练习几遍

class Solution {
public:
    int height(TreeNode* root){
       if(!root) return 0;
        int left=height(root->left);
        if(left==-1) return -1;
        int right=height(root->right);
        if(right==-1) return -1;
        if(abs(left-right)>1) return -1;
        return max(left,right)+1;
    }
    bool isBalanced(TreeNode* root) {
        return height(root)!=-1;
    }
};

111 Minimum Depth of Binary Tree33.0%Easy 

与求最大树类似,只不过要考虑一个子树是0,另一个不是零的情况要特殊处理

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.

class Solution {
public:
    int minDepth(TreeNode* root) {
        if(!root) return 0;
        int left=minDepth(root->left);
        int right=minDepth(root->right);
        if(!left&&right) return right+1;
        if(left&&!right) return left+1;
        return (left<right?left:right)+1;
    }
};

235 Lowest Common Ancestor of a Binary Search Tree38.9%Easy

Given a binary search tree (BST), find the lowest common ancestor (LCA) of two given nodes in the BST.

According to the definition of LCA on Wikipedia: “The lowest common ancestor is defined between two nodes v and w as the lowest node in T that has both v and w as descendants (where we allow a node to be a descendant of itself).”

        _______6______
       /              \
    ___2__          ___8__
   /      \        /      \
   0      _4       7       9
         /  \
         3   5

For example, the lowest common ancestor (LCA) of nodes 2 and 8 is 6. Another example is LCA of nodes 2 and 4 is 2, since a node can be a descendant of itself according to the LCA definition.

class Solution {
public:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        if(!root) return nullptr;
        int point= root->val;
        if((p->val<=point&&q->val>=point)||
          (p->val>=point&&q->val<=point))
            return root;
        if(p->val<point) return lowestCommonAncestor(root->left,p,q);
        else return lowestCommonAncestor(root->right,p,q);
            }
};

617. Merge Two Binary Trees 合并两个二叉树 简单

Given two binary trees and imagine that when you put one of them to cover the other, some nodes of the two trees are overlapped while the others are not.

You need to merge them into a new binary tree. The merge rule is that if two nodes overlap, then sum node values up as the new value of the merged node. Otherwise, the NOT null node will be used as the node of new tree.

Example 1:

Input: 
	Tree 1                     Tree 2                  
          1                         2                             
         / \                       / \                            
        3   2                     1   3                        
       /                           \   \                      
      5                             4   7                  
Output: 
Merged tree:
	     3
	    / \
	   4   5
	  / \   \ 
	 5   4   7

Note: The merging process must start from the root nodes of both trees.

class Solution {
public:
    TreeNode* mergeTrees(TreeNode* t1, TreeNode* t2) {
        if(!t1&&!t2) return nullptr;
        if(!t1&&t2) return t2;
        if(!t2&&t1) return t1;
        if(t1&&t2)
            t1->val+=t2->val;
        t1->left=mergeTrees(t1->left,t2->left);
        t1->right=mergeTrees(t1->right,t2->right);
        return t1;
        
    }
};
参考方法:迭代方法 没有尝试

以下代码是自己写的,调试不通过

class Solution {
public:
    TreeNode* mergeTrees(TreeNode* t1, TreeNode* t2) {
       stack<TreeNode*> s;
        s.push(t1);
        s.push(t2);
        while(!s.empty())
        {
            TreeNode* t2Node=s.top();
            s.pop();
            TreeNode* t1Node=s.top();
            s.pop();
            if(!t1Node&&!t2Node) continue;
            
            if(t1Node&&t2Node) {
                t1Node->val+=t2Node->val;
                if(t1Node->left&&t2Node->left)
                {
                    s.push(t1Node->left);
                    s.push(t2Node->left);
                }
                else if(t2Node->left)
                    t1Node->left=t2Node->left;
                if(t1Node->right&&t2Node->right)
                {
                    s.push(t1Node->right);
                    s.push(t2Node->right);
                }
                else  if(t2Node->right)
                    t1Node->right=t2Node->right;
            }
            else if(t2Node) t1Node=t2Node;  //这个并不能将t1更新
        }
        return t1;
    }
};

正确答案:

class Solution {
public:
    TreeNode* mergeTrees(TreeNode* t1, TreeNode* t2) {
       stack<TreeNode*> s;
        if(!t1) return t2;
        s.push(t1);
        s.push(t2);
        while(!s.empty())
        {
            TreeNode* t2Node=s.top();
            s.pop();
            TreeNode* t1Node=s.top();
            s.pop();
            if(! t1Node||! t2Node) continue;
            t1Node->val+=t2Node->val;
            if(t1Node->left)
            {
                s.push(t1Node->left);
                s.push(t2Node->left);
            }
            else
                t1Node->left=t2Node->left;
            if(t1Node->right)
            {
                s.push(t1Node->right);
                s.push(t2Node->right);
            }
            else
                t1Node->right=t2Node->right;  
        }
        return t1;
653. Two Sum IV - Input is a BST

Given a Binary Search Tree and a target number, return true if there exist two elements in the BST such that their sum is equal to the given target.

Example 1:

Input: 
    5
   / \
  3   6
 / \   \
2   4   7

Target = 9

Output: True

Example 2:

Input: 
    5
   / \
  3   6
 / \   \
2   4   7

Target = 28

Output: False

class Solution {
public:
    bool findTarget(TreeNode* root, int k) {
        set<int> flag;
        return findT(root,k,flag);
    }
    bool findT(TreeNode* root,const int& k,set<int>& flag){
        if(!root) return false;
        if(flag.find(k-root->val)!=flag.end())
            return true;
        else
        {
            flag.insert(root->val);
        }
        return findT(root->left,k,flag)||findT(root->right,k,flag); 
    }
};

606. Construct String from Binary Tree

You need to construct a string consists of parenthesis and integers from a binary tree with the preorder traversing way.

The null node needs to be represented by empty parenthesis pair "()". And you need to omit all the empty parenthesis pairs that don't affect the one-to-one mapping relationship between the string and the original binary tree.

Example 1:

Input: Binary tree: [1,2,3,4]
       1
     /   \
    2     3
   /    
  4     

Output: "1(2(4))(3)"

Explanation: Originallay it needs to be "1(2(4)())(3()())",
but you need to omit all the unnecessary empty parenthesis pairs.
And it will be "1(2(4))(3)".

Example 2:

Input: Binary tree: [1,2,3,null,4]
       1
     /   \
    2     3
     \  
      4 

Output: "1(2()(4))(3)"

Explanation: Almost the same as the first example,
except we can't omit the first parenthesis pair to break the one-to-one mapping relationship between the input and the out
自己的解法:通过
class Solution {
public:
    string tree2str(TreeNode* root){
        string temp;
        if(root)
            temp=to_string(root->val);
        else return temp;
        if(root->left)
        {
            string s=tree2str(root->left);
            temp=temp+"("+s+")";
        }
        if(root->right)
        {
            string s=tree2str(root->right);
            if(root->left)
                temp=temp+"("+s+")";
            else
                temp=temp+"()"+"("+s+")";
        }
        return temp;
    }
};

注意本题目有迭代解法,以后再看
https://leetcode.com/problems/construct-string-from-binary-tree/solution/
拓展题目:

404. Sum of Left Leaves

Find the sum of all left leaves in a given binary tree.

Example:

    3
   / \
  9  20
    /  \
   15   7

There are two left leaves in the binary tree, with values 9 and 15 respectively. Return 24.
自己的递归代码。通过,较简单:

class Solution {
public:
    int sumOfLeftLeaves(TreeNode* root) {
        int sum=0;
        if(root==nullptr) return sum;
        sumOfLeftLeaves(root,false,sum);
        return sum;
    }
    void sumOfLeftLeaves(TreeNode* root,bool left,int& sum){
        if(root->left==nullptr&&root->right==nullptr&&left) 
        {
            sum+=root->val;
            return ;
        }
        if(root->left)
            sumOfLeftLeaves(root->left,true,sum);
        if(root->right)
            sumOfLeftLeaves(root->right,false,sum);
        return ;
    }
    
};

题目还可以用迭代方法,以后再做:

https://leetcode.com/problems/sum-of-left-leaves/discuss/

563. Binary Tree Tilt

Given a binary tree, return the tilt of the whole tree.

The tilt of a tree node is defined as the absolute difference between the sum of all left subtree node values and the sum of all right subtree node values. Null node has tilt 0.

The tilt of the whole tree is defined as the sum of all nodes' tilt.

Example:

Input: 
         1
       /   \
      2     3
Output: 1
Explanation: 
Tilt of node 2 : 0
Tilt of node 3 : 0
Tilt of node 1 : |2-3| = 1
Tilt of binary tree : 0 + 0 + 1 = 1

Note:

  1. The sum of node values in any subtree won't exceed the range of 32-bit integer.
  2. All the tilt values won't exceed the range of 32-bit integer.
自己的代码:简单通过 这是后续遍历思想
class Solution {
public:
    int findTilt(TreeNode* root) {
        int sum=0;
        findTilt(root,sum);
        return sum;
    }
    int findTilt(TreeNode* root,int & sum){
        if(root==nullptr) return 0;
        if(root->left==nullptr&&root->right==nullptr) return root->val;
        else {
            int tempLeft=root->val+findTilt(root->left,sum);
            int tempRight=root->val+findTilt(root->right,sum);
            sum+=abs(tempLeft-tempRight);
         return tempLeft+tempRight-root->val;
        }
    }
};


别人的简洁代码:

public class Solution {
    int result = 0;
    
    public int findTilt(TreeNode root) {
        postOrder(root);
        return result;
    }
    
    private int postOrder(TreeNode root) {
        if (root == null) return 0;
        
        int left = postOrder(root.left);
        int right = postOrder(root.right);
        
        result += Math.abs(left - right);
        
        return left + right + root.val;
    }
}


337. House Robber III

The thief has found himself a new place for his thievery again. There is only one entrance to this area, called the "root." Besides the root, each house has one and only one parent house. After a tour, the smart thief realized that "all houses in this place forms a binary tree". It will automatically contact the police if two directly-linked houses were broken into on the same night.

Determine the maximum amount of money the thief can rob tonight without alerting the police.

Example 1:

     3
    / \
   2   3
    \   \ 
     3   1
Maximum amount of money the thief can rob =  3  +  3  +  1  =  7 .

Example 2:

     3
    / \
   4   5
  / \   \ 
 1   3   1
Maximum amount of money the thief can rob =  4  +  5  =  9 .
这道题,经过几个测试用例,自己改对了
错误解法:
class Solution {
public:
    int rob(TreeNode* root) {
        //自己的思路,使用递归的方式,传参的时候,加设一个标志位,这个标志位表示当前节点是否考虑在内
        if(nullptr==root) return 0;
        return max(rob(root,true),rob(root,false));
    }
    int rob(TreeNode* root,bool flag){//flag表示当前值是否算在内
        if(root->left==nullptr&&root->right==nullptr) 
        {
            if(flag) return root->val;
            else return 0;
        }
        else
        {
            int temp=0;
            if(flag)
            {
                if(root->left) temp+=rob(root->left,false);
                if(root->right) temp+=rob(root->right,false);
                return temp+root->val;
            }
            else
            {
                //这里有错误,如果当前值不包含在内,那么子节点也可以不包含在内
                if(root->left) temp+=rob(root->left,true);
                if(root->right) temp+=rob(root->right,true);
                int temp2=0;
                if(root->left) temp2+=rob(root->left,false);
                if(root->right) temp2+=rob(root->right,false);
                return max(temp,temp2);   
            }
        }
    }
};

改正:
class Solution {
public:
    int rob(TreeNode* root) {
        //自己的思路,使用递归的方式,传参的时候,加设一个标志位,这个标志位表示当前节点是否考虑在内
        if(nullptr==root) return 0;
        return max(rob(root,true),rob(root,false));
    }
    int rob(TreeNode* root,bool flag){//flag表示当前值是否算在内
        if(root->left==nullptr&&root->right==nullptr) 
        {
            if(flag) return root->val;
            else return 0;
        }
        else
        {
            int temp=0;
            if(flag)
            {
                if(root->left) temp+=rob(root->left,false);
                if(root->right) temp+=rob(root->right,false);
                return temp+root->val;
            }
            else
            {
                //这里有错误,如果当前值不包含在内,那么子节点也可以不包含在内
                int left=0,right=0;
                if(root->left) 
                {
                    left=max(rob(root->left,true),rob(root->left,false));
             }
                             
                if(root->right) 
                {
                    right=max(rob(root->right,true),rob(root->right,false));
                }
                return left+right;
            }
        }
    }
};


114. Flatten Binary Tree to Linked List 右节点优先的后序遍历

Given a binary tree, flatten it to a linked list in-place.

For example,
Given

         1
        / \
       2   5
      / \   \
     3   4   6

The flattened tree should look like:
   1
    \
     2
      \
       3
        \
         4
          \
           5
            \
             6
思路是从最后一个节点考虑,pre储存当前已经完成的首节点,采用的是右节点优先的后序遍历。
class Solution {
public:
    void flatten(TreeNode* root) {
        if(root==nullptr) return ;
        flatten(root->right);
        flatten(root->left);
        root->right=pre;
        root->left=nullptr;
        pre=root;
    }
    private:
    TreeNode* pre=nullptr;
};

116. Populating Next Right Pointers in Each Node

Given a binary tree

    struct TreeLinkNode {
      TreeLinkNode *left;
      TreeLinkNode *right;
      TreeLinkNode *next;
    }

Populate each next pointer to point to its next right node. If there is no next right node, the next pointer should be set to NULL.

Initially, all next pointers are set to NULL.

Note:

  • You may only use constant extra space.
  • You may assume that it is a perfect binary tree (ie, all leaves are at the same level, and every parent has two children).

For example,
Given the following perfect binary tree,

         1
       /  \
      2    3
     / \  / \
    4  5  6  7

After calling your function, the tree should look like:

         1 -> NULL
       /  \
      2 -> 3 -> NULL
     / \  / \
    4->5->6->7 -> NULL
//递归方法
class Solution {
public:
    void connect(TreeLinkNode *root) {
        //自己的思路,使用层序遍历,使用一个队列,弹出的元素指向对头元素
        //但是只能使用constant空间
        //正规思路:使用前序遍历,主要注意的地方是不是同一个子树的节点如何处理
        if(root==nullptr) return ;
        if(root->left)//左子树存在的话,右子树也存在(题目设定)
        {
            root->left->next=root->right;
        if(root->next)
            root->right->next=root->next->left;
        }
        connect(root->left);
        connect(root->right);
    }
};
迭代方法:使用的实际上是层序遍历
void connect(TreeLinkNode *root) {
    if(!root)
        return;
    while(root -> left)
    {
        TreeLinkNode *p = root;
        while(p)
        {
            p -> left -> next = p -> right;
            if(p -> next)
                p -> right -> next = p -> next -> left;
            p = p -> next;
        }
        root = root -> left;
    }
}

117. Populating Next Right Pointers in Each Node II

Follow up for problem "Populating Next Right Pointers in Each Node".

What if the given tree could be any binary tree? Would your previous solution still work?

Note:

  • You may only use constant extra space.

For example,
Given the following binary tree,

         1
       /  \
      2    3
     / \    \
    4   5    7

After calling your function, the tree should look like:

         1 -> NULL
       /  \
      2 -> 3 -> NULL
     / \    \
    4-> 5 -> 7 -> NULL
自己做的,借鉴上一个题目:这里实际上使用的是右节点优先的前序遍历,
class Solution {
public:
    void connect(TreeLinkNode *root) {
        if(root==nullptr) return ;
        if(root->left)//左子树存在的话,右子树也存在(题目设定)
        {
            if(root->right)
            root->left->next=root->right;
            else
            {
                TreeLinkNode* next=root->next;
                while(next)
                {
                    if(next->left) 
                    {
                        root->left->next=next->left;
                        break;
                    }
                    else if(next->right)
                    {
                        root->left->next=next->right;
                        break;
                    }
                    else
                        next=next->next;
                }
            }
        }
         if(root->right)
         {
             TreeLinkNode* next=root->next;
             while(next)
                {
                    if(next->left) 
                    {
                        root->right->next=next->left;
                        break;
                    }
                    else if(next->right)
                    {
                        root->right->next=next->right;
                        break;
                    }   
                    else
                        next=next->next;
                }
         }
        connect(root->right);//注意这里要先遍历右边,再遍历左边,因为左边的结构依赖于递归上层的构建和右边的构建,但是如果先遍历左子树,
        //同一层右边还没有形成
        connect(root->left);
    }
};

其他方法:

173. Binary Search Tree Iterator

mplement an iterator over a binary search tree (BST). Your iterator will be initialized with the root node of a BST.

Calling next() will return the next smallest number in the BST.

Note: next() and hasNext() should run in average O(1) time and uses O(h) memory, where h is the height of the tree.

class BSTIterator {
public:
    BSTIterator(TreeNode *root) {
        pushAll(root);
    }


    /** @return whether we have a next smallest number */
    bool hasNext() {
        return !Stack.empty();
    }


    /** @return the next smallest number */
    int next() {
        TreeNode* node=Stack.top();
        Stack.pop();
        pushAll(node->right);
        return node->val;
    }
    void pushAll(TreeNode* root){
        for(;root;Stack.push(root),root=root->left);
    }
    private:
    stack<TreeNode*> Stack;
};


199. Binary Tree Right Side View

Given a binary tree, imagine yourself standing on the right side of it, return the values of the nodes you can see ordered from top to bottom.

For example:
Given the following binary tree,

   1            <---
 /   \
2     3         <---
 \     \
  5     4       <---

You should return [1, 3, 4].

我的思路:

使用层序遍历的迭代方法,使用双端队列,每一层返回保存最后一个元素

class Solution {
public:
    vector<int> rightSideView(TreeNode* root){
        if(root==nullptr) return res;
        deque<TreeNode*> que;
        que.push_back(root);
        while(!que.empty())
        {
            res.push_back(que.back()->val);
            int n=que.size();
            for(int i;i<n;i++)
            {
                TreeNode* node=que.front();
                que.pop_front();
                if(node->left)
                    que.push_back(node->left);
                if(node->right)
                    que.push_back(node->right);
            }
        }
        return res;
    }
    
    vector<int> res;
};
222. Count Complete Tree Nodes

Given a complete binary tree, count the number of nodes.

Definition of a complete binary tree from Wikipedia:
In a complete binary tree every level, except possibly the last, is completely filled, and all nodes in the last level are as far left as possible. It can have between 1 and 2h nodes inclusive at the last level h.

class Solution {
public:
    int countNodes(TreeNode* root) {
        int h=height(root);
        return h<0?0:height(root->right)==h-1?(1<<h)+countNodes(root->right):(1<<(h-1))+countNodes(root->left);
    }
    int height(TreeNode* root){
        return root==nullptr?-1:1+height(root->left);
    }
};
变种:
class Solution {
public:
    int countNodes(TreeNode* root) {
        int h=height(root);
        int num=0;
        while(root){
            if(height(root->right)==h-1)
            {
                num+=1<<h;
                root=root->right;
            }
            else
            {
                num+=1<<h-1;
                root=root->left;
            }
            h--;
        }
        return num;
    }
    int height(TreeNode* root){
        return root==nullptr?-1:1+height(root->left);
    }
};





230. Kth Smallest Element in a BST

Given a binary search tree, write a function kthSmallest to find the kth smallest element in it.

Note: 
You may assume k is always valid, 1 ? k ? BST's total elements.

Follow up:
What if the BST is modified (insert/delete operations) often and you need to find the kth smallest frequently? How would you optimize the kthSmallest routine?

方法1:计算左子树的数目,如果大于k,则转到左节点,否则转到右节点。复杂度较高,有很多重复遍历

class Solution {
public:
    int kthSmallest(TreeNode* root, int k) {
        int count=countNode(root->left);
        if(k<=count) return kthSmallest(root->left,k);
        if(k>count+1)
            return kthSmallest(root->right,k-count-1);
       return root->val;
    }
    int countNode(TreeNode* node){
        if(node==nullptr) return 0;
        return 1+countNode(node->left)+countNode(node->right);
    }
};
方法2: 递归的中序遍历

class Solution {
public:
    int kthSmallest(TreeNode* root, int k) {
       count=k;
       kthSmallest(root);
        return res;
    }
    void kthSmallest(TreeNode* root){
        if(root->left) kthSmallest(root->left);
        count--;
        if(count==0)
        {
         res=root->val;
            return ;
        }
        if(root->right)
            kthSmallest(root->right);
    }
    int count=0;
    int res=0;
};

方法3:迭代得中序遍历



236. Lowest Common Ancestor of a Binary Tree

Given a binary tree, find the lowest common ancestor (LCA) of two given nodes in the tree.

According to the definition of LCA on Wikipedia: “The lowest common ancestor is defined between two nodes v and w as the lowest node in T that has both v and w as descendants (where we allow a node to be a descendant of itself).”

        _______3______
       /              \
    ___5__          ___1__
   /      \        /      \
   6      _2       0       8
         /  \
         7   4

For example, the lowest common ancestor (LCA) of nodes 5 and 1 is 3. Another example is LCA of nodes 5 and 4 is 5, since a node can be a descendant of itself according to the LCA definition.

剑指offer 思路:不通过
class Solution {
public:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        if(root==nullptr||p==nullptr||q==nullptr)
            return nullptr;
        list<TreeNode*> plist;
        getList(root,p,plist);
        list<TreeNode*> qlist;
        getList(root,q,qlist);
        return compareList(plist,qlist);
    }
    bool getList(TreeNode* root,TreeNode* p,list<TreeNode*>& plist){
        if(root==p) return true;
        plist.push_back(root);
        bool found=false;
        if(found==false&&root->left)
            found=getList(root->left,p,plist);
        if(found==false&&root->right)
            found=getList(root->right,p,plist);
        if(found==false)
            plist.pop_back();
        return found;
    }
    TreeNode* compareList(list<TreeNode*>& plist,list<TreeNode*>& qlist){
        list<TreeNode*>::const_iterator pi=plist.begin();
        list<TreeNode*>::const_iterator qi=qlist.begin();
        TreeNode* res=nullptr;
        while(pi!=plist.end()&&qi!=qlist.end())
        {
            if(*pi==*qi)
                res=*pi;
            else break;
            ++pi,++qi;
        }
        return res;
        
    } 
};

别人的方法:
1、递归方法
class Solution {
public:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        if(!root||p==root||q==root) return root;
        TreeNode* left=lowestCommonAncestor(root->left,p,q);
        TreeNode* right=lowestCommonAncestor(root->right,p,q);
        return !left?right:!right?left:root;
    } 
};
2 迭代方法
思路:建立一个哈希表,保存一个节点和节点对应的根节点。
使用一个队列,当两个节点都找到之前,做循环,依次形成这些哈希关系,都找到之后,建立一个set保存p节点的根节点,然后在set里面依次查找q的根节点,查到时,这个节点就是结果
这个算法假设两个节点都在树中
class Solution {
public:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        if(!root||!q||!p) return nullptr;
        unordered_map<TreeNode*,TreeNode*> parent;
        parent[root]=nullptr;
        set<TreeNode*> ancestor;
        stack<TreeNode*> que;
        que.push(root);
        while(parent.find(p)==parent.end()||parent.find(q)==parent.end())
        {
            TreeNode* node=que.top();
            que.pop();
            if(node->left)
            {
                parent[node->left]=node;
                que.push(node->left);
            }
            if(node->right)
            {
                parent[node->right]=node;
                que.push(node->right);
            }
            
        }
        while(p)
        {
            ancestor.insert(p);//要包含自己,因为很可能出现其中一个节点是上层节点的情况
            p=parent[p];
        }
        while(ancestor.find(q)==ancestor.end())//要包含自己,原因同上
            q=parent[q];
        return q;
    } 
};


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值