问题一:二叉树任意两个叶子间简单路径最大和

示例:

-100

/   \

2   100

/  \

10   20

思路:这个问题适用于递归思路。

首先,将问题简单化:假设包含最大和summax的简单路径经过结点A,结点A必然存在左右子树,设f(node*)函数可以求出子树叶子到子树树根最大和路径,则有summax=A.val+f(A.leftchild)+f(A.rightchild),此时,遍历树中拥有左右子树的节点,并提取最大值即可。

再假设fmax(node*)可以求出以该结点参数为根的树/子树的任意两个叶子间简单路径最大和,则可以分为三种情况:1.最大和路径经过根结点;2.最大和路径在左子树中;3.最大和路径在右子树中。比较三者取出最大值作为fmax函数的返回值。

为了简化代码,使用之前所写的创建二叉树的函数

struct tree_node;
struct tree_node{
struct tree_node *lc;
struct tree_node *rc;
int data;
};
typedef struct tree_node treenode; void pre_create_tree(treenode **T){ //递归法
int datatemp; fflush(stdin);
scanf("%d", &datatemp); if(datatemp==-1000){
*T=NULL;
}
else{
if((*T=(treenode*)malloc(sizeof(treenode)))==NULL){
exit(0);
}
else{
(*T)->data=datatemp;
(*T)->lc = (*T)->rc = NULL;
pre_create_tree(&(*T)->lc);
pre_create_tree(&(*T)->rc);
}
}
} void pre_visit_tree(treenode *T){ //递归法
if(T!=NULL){
printf("%d ", T->data);
pre_visit_tree(T->lc);
pre_visit_tree(T->rc);
}
else{
return;
}
}

这里为了方便,假设输入数据不等于-1000,那么求叶子到树根最大值函数f(node*)如下所示:

int maxpath(treenode *T){
int templc=-100000,temprc=-1000000;
if(T==NULL)
return INT_MIN;
if(T->lc==NULL&&T->rc==NULL)
return T->data;
if(T->lc!=NULL)
templc = T->data+maxpath(T->lc);
if(T->rc!=NULL)
temprc = T->data+maxpath(T->rc);
if(templc>temprc)
return templc;
else
return temprc;
}

求解任意叶子简单路径最大和fmax函数实现:

int maxs(treenode *T){
int temproot=0,templc=0, temprc=0; if(T==NULL)
return INT_MIN;
if(T->lc==NULL||T->rc==NULL){
return INT_MIN;
}
if(T->lc!=NULL&&T->rc!=NULL){
temproot=maxpath(T->lc)+maxpath(T->rc)+T->data;
}
templc = maxs(T->lc);
temprc = maxs(T->rc);
if(temproot>templc)
if(temproot>temprc)
return temproot;
else
return temprc;
else
if(templc>temprc)
return templc;
else
return temprc;
}

测试输入:-100 2 10 -1000 -1000 20 -1000 -1000 100

调用maxs函数将返回32。

问题二:我们将问题稍微变化一下,改为求任意结点间简单路径最大和,允许路径只有一个结点。

这时候递归是否有效?答案是肯定的。

看图:

a

/      \

b       c

/    \    /    \

bl   br cl   cr

把树或者子树看成上图的模式,假设我们已经实现一个函数f(node* param),根结点为参数结点param的子树,经过param结点的最大路径和(这里并不需要到达叶子)。

由上图我们对一个结点分3种情况考虑:

1.最大和路径经过结点a,即有四种可能值:a.val,a.val+f(b),a.val+f(c),a.val+f(b)+f(c);

2.最大和路径不经过结点a,且在结点a的左子树内并经过结点b,值为f(b);

3.最大和路径不经过结点a,且在结点a的右子树内并经过结点c,值为f(c)。(情况2,3是不是不需要呢?好像是的,先记着后面来改)

在这六种可能值中,取其最大值作为计算经过结点a的最大值的“可能路径”,然后遍历树中结点即可得到最大数值。

int maxpath2(treenode *T){
int templc=0,temprc=0; if(T==NULL)
return -100000;
if(T->lc==NULL&&T->rc==NULL)
return T->data;
if(T->lc!=NULL)
templc = maxpath2(T->lc);
if(T->rc!=NULL)
temprc = maxpath2(T->rc);
if(templc<=0&&temprc<=0){
return T->data;
}
else if(templc>temprc)
return T->data+templc;
else
return T->data+temprc;
} int maxs2(treenode *T){
long int temproot=0,templc=0,temprc=0;
long int sum[6],max,k; if(T==NULL)
return -100000;
if(T->lc==NULL&&T->rc==NULL)
return T->data;
memset(sum, 0, sizeof(int)*6); sum[0] = T->data;
sum[1] = maxpath2(T->lc);
sum[2] = maxpath2(T->rc);
sum[3] = T->data+sum[1];
//sum[4] = T->data+sum[2];
//sum[5] = T->data+sum[1]+sum[2]; for(k=1, temproot=sum[0]; k<4; k++){
if(sum[k]>temproot)
temproot = sum[k];
} templc = maxs2(T->lc);
temprc = maxs2(T->rc);
if(temproot>templc&&temproot>temprc)
return temproot;
else if(templc>temprc)
return templc;
else
return temprc;
}

那么我们试试以下面的二叉树为例

-100

/   \

2   100

/  \

10   -20

输入为-100 2 10 -1000 -1000 -20 -1000 -1000 100 -1000 -1000

调用maxs2结果就应该为100了(不是12)。

【Leetcode】二叉树简单路径最大和问题的更多相关文章

  1. [LeetCode] Path Sum III 二叉树的路径和之三

    You are given a binary tree in which each node contains an integer value. Find the number of paths t ...

  2. [LeetCode] Path Sum IV 二叉树的路径和之四

    If the depth of a tree is smaller than 5, then this tree can be represented by a list of three-digit ...

  3. [LeetCode] 113. Path Sum II ☆☆☆(二叉树所有路径和等于给定的数)

    LeetCode 二叉树路径问题 Path SUM(①②③)总结 Path Sum II leetcode java 描述 Given a binary tree and a sum, find al ...

  4. [LeetCode] 666. Path Sum IV 二叉树的路径和 IV

    If the depth of a tree is smaller than 5, then this tree can be represented by a list of three-digit ...

  5. 二叉树单色路径最长&amp;&amp;穿珠子

    对树的操作,特别理解递归的好处. //对于一棵由黑白点组成的二叉树,我们需要找到其中最长的单色简单路径,其中简单路径的定义是从树上的某点开始沿树边走不重复的点到树上的 //另一点结束而形成的路径,而路 ...

  6. 二叉树单色路径最长&&穿珠子

    对树的操作,特别理解递归的好处. //对于一棵由黑白点组成的二叉树,我们需要找到其中最长的单色简单路径,其中简单路径的定义是从树上的某点开始沿树边走不重复的点到树上的 //另一点结束而形成的路径,而路 ...

  7. LeetCode二叉树实现

    LeetCode二叉树实现 # 定义二叉树 class TreeNode: def __init__(self, x): self.val = x self.left = None self.righ ...

  8. LeetCode:简化路径【71】

    LeetCode:简化路径[71] 题解参考天码营:https://www.tianmaying.com/tutorial/LC71 题目描述 给定一个文档 (Unix-style) 的完全路径,请进 ...

  9. leetcode二叉树题目总结

    leetcode二叉树题目总结 题目链接:https://leetcode-cn.com/leetbook/detail/data-structure-binary-tree/ 前序遍历(NLR) p ...

随机推荐

  1. [poj 1039]Pipes[线段相交求交点]

    题意: 无反射不透明管子, 问从入口射入的所有光线最远能到达的横坐标. 贯穿也可. 思路: 枚举每一组经过 up [ i ] 和 down [ j ] 的直线, 计算最远点. 因为无法按照光线生成的方 ...

  2. Shell变量替换,命令替换,转义字符

    如果表达式中包含特殊字符,Shell 将会进行替换.例如,在双引号中使用变量就是一种替换,转义字符也是一种替换. 举个例子: #!/bin/bash a=10 echo -e "Value ...

  3. ARM架构和X86架构对比

    转载地址 我们就ARM架构的系统与X86架构系统的特性进行一个系统分析,方便用户在选择系统时进行理性.合理的比价分析. 一.性能: X86结构的电脑无论如何都比ARM结构的系统在性能方面要快得多.强得 ...

  4. windows phone中,将crash report记录下来,写入文件,方便分析

    APP出现crash(崩溃)总是不能忍的 当我们连接调试器调试的时候,发现每当APP崩溃的时候 程序都会走到App.xaml.cs中的 // Code to execute on Unhandled ...

  5. 1、elasticsearch简介

    1.elasticsearch简介 中文帮助文档地址:http://es.xiaoleilu.com/ • Elasticsearch是一个基于Lucene的实时的分布式搜索和分析引擎.设计用于云计算 ...

  6. php 原理相关

    [PHP 运行方式(PHP SAPI介绍)] http://www.phpddt.com/php/php-sapi.html [PHP内核探索:从SAPI接口开始]http://www.nowamag ...

  7. EasyUI DataGrid定制默认属性名称

    EasyUI DataGrid绑定服务器返回Json数据的解决方案 1. 服务器返回的数据对象格式,及初始化返回值 public class RequestResult { private int c ...

  8. vector的内存分配与释放

    1. vector内存分配 <Effective STL>中"条款14":使用reserve来避免不必要的重新分配 关于STL容器,最神奇的事情之一是只要不超过它们的最 ...

  9. 【贪心】【Uva11729】 Commando War

    你有n个部下,每个部下需要完成一项任务.第i个部下需要你花Bi分钟交待任务,然后他会立刻独立地.无间断地执行Ji分钟后完成任务.你需要选择交待任务的顺序,使得所有任务尽早执行完毕(即最后一个执行完的任 ...

  10. 封装一些数据库SQLCipher的方法(增、删、改、查)

    上一篇随笔只是简单的说了一下使用SQLCipher框架,介绍的比较笼统,可能看一遍之后更加蒙圈了,为了更好的使用这个数据库,整理了我在公司项目的需要用的方法,包括创建表,插入数据,更新数据,搜索查询数 ...