【问题标题】:Finding the closest number in a Binary Tree to a given target在二叉树中找到最接近给定目标的数字
【发布时间】:2021-11-21 08:54:43
【问题描述】:

我有一个非常简单的二叉树

class TreeNode(object):
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None

root = TreeNode(8)
root.left = TreeNode(5)
root.right = TreeNode(14)
root.left.left = TreeNode(4)
root.left.right = TreeNode(6)
root.left.right.left = TreeNode(8)
root.left.right.right = TreeNode(7)
root.right.right = TreeNode(24)
root.right.right.left = TreeNode(22)

我实现了一个函数来查找树中最接近目标的数字 (19):

def closest_value(root, target, closest=0):
    if abs(root.val - target) < abs(closest - target):
        closest = root.val
        print(closest)
    if root.left is not None:
        closest_value(root.left, target, closest)
    if root.right is not None:
        closest_value(root.right, target, closest)
    return closest

结果显然应该是 22,但我得到的是 8。令人惊讶的是,当我打印以下所有“最接近”的数字时,该函数似乎工作正常:它打印:8、14、22。但为什么不呢?它返回最近的最近数字:22?

result = closest_value(root, 19)
print('result:', result)

【问题讨论】:

  • root.right.right.left 的作业在我看来完全崩溃了
  • @raganjosh 你是什么意思坏了?所有节点都以相同的方式创建
  • 因为我从未见过这样的事情。属性上的属性?您认为这将有多大的可扩展性?
  • 对于设置虚拟数据,我看不出有什么问题。分配给属性的属性非常好。无论如何,问题是关于递归算法的。
  • 您需要从递归调用中捕获返回值,并返回两者中最接近的值。

标签: python binary-tree closest


【解决方案1】:

第一次调用closest_value 中的最接近的值不会在 if 语句中更新。只需将值分配给closest

def closest_value(root, target, closest=0):
    if abs(root.val - target) < abs(closest - target):
        closest = root.val
    if root.left is not None:
        #assign value
        closest = closest_value(root.left, target, closest)
    if root.right is not None:
        #assign value
        closest = closest_value(root.right, target, closest)
    return closest

result = closest_value(root, 19)
print(result)
# 22

【讨论】:

    【解决方案2】:

    您没有使用递归调用的结果来确定最终返回值。

    也许一种更简单的方法,不按下默认参数会更容易:

    def closest(node,value):
        if not node: return float('inf') 
        vals = [node.val, closest(node.left,value), closest(node.right,value)]
        return min(vals,key=lambda v:abs(v-value))
    
    closest(root,19) # 22
    

    一个问题是,这是一种 O(n) 方法,它将遍历整个二叉树而不利用层次结构。对于已排序的二叉树,您可以获得 O(logN) 的解决方案,通过实现一对二分搜索函数来查找值为 = 的最近节点。然后只应用在 O(logN) 时间内找到的这两个节点之间的绝对值比较。

    def findLE(node,value):
        if not node: return None
        if node.val == value: return node
        if node.val<value:    return findLE(node.right,value) or node
        return findLE(node.right,value)
    
    def findGE(node,value):
        if not node: return None
        if node.val == value: return node
        if node.val>value:    return findGE(node.left,value) or node
        return findGE(node.right,value)
    
    def closestValue(node,value):
        less = findLE(node,value)
        more = findGE(node,value)
        if more and less:
            return min(more.val,less.val,key=lambda v:abs(v-value))
        return (more or less).val
    

    请注意,由于节点 6 左侧的 8,您的二叉树未按排序顺序:

          8
       __/ \_
      5      14
     / \       \
    4   6       24
       / \     /
      8   7  22
    

    (可以找到二叉树打印函数here

    【讨论】:

    • 第二种方法要求它是一个实际的排序二叉树,对吗?可能值得一提的是,因为问题中的示例数据不是(完全)按顺序排列的。
    • 确实,我没有意识到示例中的二叉树的元素顺序不正确。 (相应地调整了我的答案)
    猜你喜欢
    • 2013-06-15
    • 1970-01-01
    • 2021-12-30
    • 2011-03-10
    • 1970-01-01
    • 2021-01-28
    • 1970-01-01
    • 1970-01-01
    • 2021-12-28
    相关资源
    最近更新 更多