1. 程式人生 > >leetcode算法題2: 合並兩個二叉樹。遞歸,如何切入並保持清醒?

leetcode算法題2: 合並兩個二叉樹。遞歸,如何切入並保持清醒?

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) {

}12345678910111234567891011

題意:合並兩個二叉樹。規則是,對應的兩個結點如果有重疊就求和(比如更改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: 合並兩個二叉樹。遞歸,如何切入並保持清醒?