leetcode算法题2: 合并两个二叉树。递归,如何切入并保持清醒?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了leetcode算法题2: 合并两个二叉树。递归,如何切入并保持清醒?相关的知识,希望对你有一定的参考价值。

/* 
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. 
*//**

 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */
struct TreeNode* mergeTrees(struct TreeNode* t1, struct TreeNode* t2) {

}

*/

题意:合并两个二叉树。规则是,对应的两个结点如果有重叠就求和(比如更改val),如果不重叠就使用非空的结点的值。(不考虑树释放的问题。)

技术分享

办法1

* 把t2并到t1,最终返回t1。

* 记录t1,作为最终的返回。进入递归函数。

* 如果t1与t2都不为空,此时需要递归:

???* 求和,更改t1->val。

???* 左子树递归,并把结果赋值给t1->left。

???* 右子树递归,并把结果赋值给t1->right。

???* 返回t1。

* 否则,结束递归,返回t1?t1:t2。

* 注意,递归的返回值要利用上,这是更换子树的机会。

强化与提问

* 递归关键点:

???* 只考虑两层,root跟(root->left && root->right)。

???* 何时递归

???* 何时结束递归

* 方法不一样时,要留意的点很可能也不一样。在一个方法中容易犯的错,在另一个方法中可能根本就不存在。所以,想办法有时候是解决问题的关键。

* 代码上的细节,有时决定了成败。


#include <stdio.h>

struct TreeNode {
  int val;
  struct TreeNode *left;
  struct TreeNode *right;
};

struct TreeNode* merge(struct TreeNode* l, struct TreeNode* r) {
    if (l && r) {
        l->val += r->val;
        l->left = merge(l->left, r->left);
        l->right = merge(l->right, r->right);
        return l;
    }
    else {
        return l?l:r;
    }
}

struct TreeNode* mergeTrees(struct TreeNode* t1, struct TreeNode* t2) {
   struct TreeNode* ret = t1;
   merge(t1, t2);
   return ret;
}

void printTree(struct TreeNode* tree) {
    if (tree) {
        printf("%d, ", tree->val);
        printTree(tree->left);
        printTree(tree->right);
    }
    else {
        printf("NULL, ");
    }
}

int main(int argc, char *argv[])
{
    struct TreeNode n1={1,0,0};
    struct TreeNode n2={3,0,0};
    struct TreeNode n3={2,0,0};
    struct TreeNode n4={5,0,0};
    n1.left = &n2;
    n1.right = &n3;
    n2.left = &n4;
    struct TreeNode r1={2,0,0};
    struct TreeNode r2={1,0,0};
    struct TreeNode r3={3,0,0};
    struct TreeNode r4={4,0,0};
    struct TreeNode r5={7,0,0};
    r1.left = &r2;
    r1.right = &r3;
    r2.right = &r4;
    r3.right = &r5;
    printf("tree1:\n");
    printTree(&n1);
    printf("\ntree2:\n");
    printTree(&r1);
    printf("\nmerged:\n");
    struct TreeNode* ret = mergeTrees(&n1, &r1);
    printTree(ret);
    printf("\n");

    return 0;
}




以上是关于leetcode算法题2: 合并两个二叉树。递归,如何切入并保持清醒?的主要内容,如果未能解决你的问题,请参考以下文章

⭐算法入门⭐《深度优先搜索》简单02 —— LeetCode 617. 合并二叉树

leetcode刷题29.合并二叉树——Java版

[LeetCode]617. 合并二叉树(递归)

一文通数据结构与算法之——二叉树+常见题型与解题策略+Leetcode经典题

二叉树算法总结

leetcode617 合并二叉树(Easy)