binary tree recursion problem

1. Recover Binary Search Tree

Two elements of a binary search tree (BST) are swapped by mistake.

Recover the tree without changing its structure.

Note:
A solution using O( n ) space is pretty straight forward. Could you devise a constant space solution?

confused what "{1,#,2,3}" means? > read more on how binary tree is serialized on OJ.


OJ's Binary Tree Serialization:

The serialization of a binary tree follows a level order traversal, where '#' signifies a path terminator where no node exists below.

Here's an example:

   1
  / \
 2   3
    /
   4
    \
     5
The above binary tree is serialized as  "{1,2,3,#,#,4,#,#,5}".

题意二叉查找树不合法,有两个节点的值被交换了,找出这两个节点并且不改变树的结构,使得二叉查找树合法,常数空间限制。


这题的要点就是想到使用树的递归中序遍历,因为二叉查找树合法的情况,中序遍历的值是从小到大排列的。

当出现当前值比前一个值小的时候,就是存在不合法的节点。

用pre存中序遍历时当前节点的前一个节点,方便值的大小对比,用s1,s2记录这两个不合法序列的位置,s1存较大的值,s2存较小的值。

最后把两个不合法的值交换。

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. void getTwoNode(TreeNode *root,TreeNode *&n1, TreeNode*&n2, TreeNode*&pre){  
  2.     if(!root ) return;  
  3.     getTwoNode(root->left, n1, n2, pre);  
  4.     if(pre && pre->val > root->val){  
  5.         n2 = root;  
  6.         if(n1==NULL)  
  7.             n1 = pre;  
  8.   
  9.     }  
  10.     pre = root;  
  11.     getTwoNode(root->right,n1,n2,pre);  
  12. }  
  13. void recoverTree(TreeNode *root) {  
  14.     TreeNode *n1=NULL, *n2=NULL, *pre = NULL;  
  15.     if(!root) return;  
  16.     getTwoNode(root,n1,n2,pre);  
  17.     if(n1 && n2){  
  18.         int temp = n1->val;  
  19.         n1->val = n2->val;  
  20.         n2->val = temp;  
  21.     }  
  22. }  


2. Binary Tree Maximum Path Sum

Given a binary tree, find the maximum path sum.

The path may start and end at any node in the tree.

For example:
Given the below binary tree,

       1
      / \
     2   3

Return 6.

题目要求找出二叉树中路径的最大和

有最大和的路径有一下三种情况:

1. 只有一个节点

2. 根节点+左子树

3. 根节点+右子树

4. 根节点+左子树+右子树

trace the four path and pick up the max path

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. int Getmax(TreeNode *root, int &maxCrossRoot){  
  2.         if(root == NULL) return 0;  
  3.         int left = Getmax(root->left, maxCrossRoot);  
  4.         int right = Getmax(root->right, maxCrossRoot);  
  5.         int rMax = root->val;  
  6.   
  7.         if(left>0)  
  8.             rMax += left;  
  9.         if(right>0)  
  10.             rMax += right;  
  11.         maxCrossRoot = std::max(maxCrossRoot, rMax);  
  12.   
  13.         return std::max(root->val, std::max(root->val+left, root->val+right));  
  14.     }  
  15. int maxPathSum(TreeNode *root) {  
  16.     int maxCrossRoot = INT_MIN;  
  17.     int maxEndbyRoot = Getmax(root, maxCrossRoot);  
  18.     return std::max(maxEndbyRoot,maxCrossRoot);  
  19. }  



3. Sum Root to Leaf Numbers

Given a binary tree containing digits from 0-9 only, each root-to-leaf path could represent a number.

An example is the root-to-leaf path 1->2->3 which represents the number 123.

Find the total sum of all root-to-leaf numbers.

For example,

    1
   / \
  2   3

The root-to-leaf path 1->2 represents the number 12.
The root-to-leaf path 1->3 represents the number 13.

Return the sum = 12 + 13 = 25.

问题是要求出 所有从根节点到叶子节点的路径和 的总和

这题与上一题类似,不同之处是需要添加变量记录之前的路径和

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. void sumSubpath(TreeNode* root, int &sum, int path){  
  2.     if(root == NULL) return;  
  3.     path = path*10+ root->val;  
  4.     if(root->left == NULL && root->right == NULL){  
  5.         sum += path;  
  6.         return;  
  7.     }  
  8.     sumSubpath(root->left, sum, path);  
  9.     sumSubpath(root->right, sum, path);  
  10. }  
  11. int sumNumbers(TreeNode *root) {  
  12.     int sum = 0;  
  13.     int path = 0;  
  14.     sumSubpath(root,sum,path);  
  15.     return sum;  
  16. }  

4. path sum

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      1

return true, as there exist a root-to-leaf path 5->4->11->2 which sum is 22.

每当计算到叶子节点时,比较是否与目标值相同

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. void judgeSubpath(TreeNode* root, int sum, int target, bool &result){  
  2.     if(root == NULL) return;  
  3.     sum += root->val;  
  4.     if(root->left == NULL && root->right == NULL){  
  5.         if(sum == target)  
  6.             result = true;  
  7.         return;  
  8.     }  
  9.     judgeSubpath(root->left,sum,target,result);  
  10.     judgeSubpath(root->right,sum,target,result);  
  11. }  
  12. //第二种写法  
  13. bool judgePathSum(TreeNode* root, int sum, int target){  
  14.     if(root == NULL) return false;  
  15.     sum += root->val;  
  16.     if(root->left == NULL && root->right == NULL){  
  17.         if(sum == target)  
  18.             return true;  
  19.         else  
  20.             return false;  
  21.     }  
  22.     return judgePathSum(root->left,sum,target)  
  23.     || judgePathSum(root->right, sum,target);  
  24. }  
  25.   
  26. bool hasPathSum(TreeNode *root, int sum) {  
  27.     bool result = false;  
  28.     judgeSubpath(root,0,sum,result);  
  29.     return result;  
  30. }  

5. Path Sum II

Given a binary tree and a sum, find all root-to-leaf paths where each path's sum equals the given sum.

For example:
Given the below binary tree and  sum = 22 ,
              5
             / \
            4   8
           /   / \
          11  13  4
         /  \    / \
        7    2  5   1

return

[
   [5,4,11,2],
   [5,8,4,5]
]
[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. 二叉树递归,计算每条Path的和并比较,可以与前面几道题比较找到灵感  
[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1.   
[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. void GetsumPath(vector<vector<int>> &result,  
  2.                 vector<int> &path,  
  3.                 int target,  
  4.                 int sum,  
  5.                 TreeNode *root){  
  6.     if(root == NULL) return;  
  7.     sum += root->val;  
  8.     path.push_back(root->val);  
  9.     if(target == sum && root->left == NULL && root->right == NULL){  
  10.         result.push_back(path);  
  11.     }else{  
  12.         if(root->left != NULL)  
  13.             GetsumPath(result,path,target,sum,root->left);  
  14.         if(root->right != NULL)  
  15.             GetsumPath(result,path,target,sum,root->right);  
  16.     }  
  17.     path.pop_back();  
  18.     sum -= root->val;  
  19.     return;  
  20. }  
  21. vector<vector<int> > pathSum(TreeNode *root, int sum) {  
  22.      vector<vector<int>> result;  
  23.      vector<int> path;  
  24.      GetsumPath(result,path,sum,0,root);  
  25.      return result;  
  26. }  


6. 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

从根节点一层递归连接left---right到最后一层,

处理完当前层后处理下一层

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. void connect(TreeLinkNode *root) {  
  2.      if(root == NULL) return;  
  3.      if(root->left != NULL)  
  4.         root->left->next = root->right;  
  5.      if(root->right != NULL)  
  6.         root->right->next = root->next ? root->next->left:NULL;  
  7.      connect(root->left);  
  8.      connect(root->right);  
  9. }  

7. 

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

思路,与上一题类似,这里要多考虑如何找到下一个有效节点,需要先连接右边节点

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. void connectAnyBT(TreeLinkNode *root) {  
  2.      if(root == NULL) return;  
  3.      TreeLinkNode *p = root->next;  
  4.      while(p != NULL){  
  5.         if(p->left != NULL){  
  6.             p = p->left;  
  7.             break;  
  8.         }  
  9.         if(p->right != NULL){  
  10.             p = p->right;  
  11.             break;  
  12.         }  
  13.         p = p->next;  
  14.      }  
  15.      if(root->right != NULL){  
  16.         root->right->next = p;  
  17.      }  
  18.      if(root->left != NULL){  
  19.         root->left->next = root->right ? root->right : p;  
  20.      }  
  21.      connectAnyBT(root->right);  
  22.      connectAnyBT(root->left);  
  23. }  

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值