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;
}

转载于:https://my.oschina.net/u/3613477/blog/1417325

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值