二叉树中的最长路径_二叉树中最长的链

二叉树中的最长路径

A binary tree is a special type of graph where each parent node has exactly two child nodes.

二叉树是一种特殊类型的图,其中每个父节点正好有两个子节点。

Today’s puzzle, then, is to traverse the binary tree in order to find the longest chain in the binary tree!

那么,今天的难题是遍历二叉树,以便找到二叉树中最长的链!

Before we can do that, we have to know what is a chain in a binary tree (or what I meant by it since I came up with the name…)

在我们这样做之前,我们必须知道什么是二叉树中的链(或者自从我想出这个名字以来我的意思是……)。

Definition:

定义:

  • A chain is a connected list of nodes with the same value.

    链是具有相同值的节点的连接列表。

Image for post

In the above graph, there is a chain of 1’s, with a length of 2, since the chain has 2 edges in it.

在上图中,由于链中有2条边,因此链的长度为2,为1。

One more detail that’s actually quite important to realize:

实际上要实现的一个更重要的细节是:

Image for post

Notice in this case the chain of 1’s spans the left child and the right child, it is still a valid chain, of length 3.

请注意,在这种情况下,1的链条跨越左子项和右子项,它仍然是有效链,长度为3。

So now I present you with a binary tree:

现在,我向您展示一个二叉树:

class Node:
def __init__(self, value, left=None, right=None):
self.value = value
self.left = left
self.right = right
tree1 = Node(1)
tree1.left = Node(1)
tree1.right = Node(1)
tree1.left.left = Node(3)
tree1.left.right = Node(1)

This is the code version of the “Binary Tree with a Cross Chain”, how do I proceed to find the longest chain and return its length, which is 3?

这是“带有交叉链的二叉树”的代码版本,如何继续查找最长的链并返回其长度,即3?

As with most tree algorithms, this probably involves recursion in some way. So does the simplest recursion work?

与大多数树算法一样,这可能以某种方式涉及递归。 那么最简单的递归有效吗?

at each node find the longest chain in its left child and right child, respectively, and add them up if the left child’s value or the right child’s value equals the parent.

在每个节点上,分别在其左子节点和右子节点中找到最长的链,如果左子节点的值或右子节点的值等于父节点的值,则将它们加起来。

Let’s try it out (hint: it’s not this easy).

让我们尝试一下(提示:这并不容易)。

def find_longest_chain(tree):
if tree is None:
return None
if tree.left is None and tree.right is None:
return 0
left_longest = find_longest_chain(tree.left)
right_longest = find_longest_chain(tree.right)
longest = 0
if left_longest is not None and tree.left.value == tree.value:
longest = longest + left_longest + 1
if right_longest is not None and tree.right.value == tree.value:
longest = longest + right_longest + 1
return longest
res = find_longest_chain(tree1)

Well, if you test out this algorithm on the tree we had, it would seem to work:

好吧,如果您在我们拥有的树上测试了该算法,它似乎可以工作:

>>> res
3

But this algorithm overlooks an important exception:

但是此算法忽略了一个重要的例外:

Image for post

In this case the longest chain is actually not the chain of 1’s, but the chain of 3’s, and its length is 5.

在这种情况下,最长的链实际上不是1的链,而是3的链,其长度为5。

let see what happens if we apply the same algorithm:

让我们看看如果应用相同的算法会发生什么:

tree2 = Node(1)
tree2.left = Node(1)
tree2.right = Node(1)
tree2.left.left = Node(3, left=Node(3, left=Node(3, left=Node(3, left=Node(3, left=Node(3))))))
tree2.left.right = Node(1)
res2 = find_longest_chain(tree2)>>> res2
3

The result is still 3.

结果仍然是3。

Why? Because our simple algorithm only finds the chain that passes through the root!

为什么? 因为我们的简单算法只能找到通过根的链!

How do we modify this then. Well, this is the trick that I need to get paid for!!

那我们该如何修改呢。 好吧,这是我需要付钱的把戏!

Just kidding, the trick is to keep a state variable:

只是在开玩笑,技巧是保留一个状态变量:

def find_longest_chain(tree, global_longest):
if tree is None:
return None
if tree.left is None and tree.right is None:
return 0
left_longest = find_longest_chain(tree.left, global_longest)
right_longest = find_longest_chain(tree.right, global_longest)
longest = 0
if left_longest is not None and tree.left.value == tree.value:
longest = longest + left_longest + 1
if right_longest is not None and tree.right.value == tree.value:
longest = longest + right_longest + 1
global_longest[0] = max(global_longest[0], longest)
return longest
def entry_find_longest_chain(tree):
longest = [0]
find_longest_chain(tree, global_longest=longest)
return longest[0]

Couple things to notice:

需要注意的几件事:

  • the global shared variable global_longest is modified by each recursion as necessary.

    全局共享变量global_longest由每次递归根据需要进行修改。

  • global_longest is a list of one integer, the reason I didn’t just pass in an integer is that integers are passed by value in Python, whereas lists are passed by reference.

    global_longest是一个整数列表,我之所以不传递整数,是因为整数在Python中是通过值传递的,而列表是通过引用传递的。

Now if I try the algorithm on the two trees:

现在,如果我在两棵树上尝试该算法:

res = entry_find_longest_chain(tree1)
>>> res
3
res2 = entry_find_longest_chain(tree2)
>>> res2
5

It works!

有用!

普通英语的Python (Python In Plain English)

Did you know that we have three publications and a YouTube channel? Find links to everything at plainenglish.io!

您知道我们有三个出版物和一个YouTube频道吗? 在plainenglish.io上找到所有内容的链接!

翻译自: https://medium.com/python-in-plain-english/longest-chain-in-a-binary-tree-8a0c4789e131

二叉树中的最长路径

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值