簡體   English   中英

在二叉樹中找到最接近給定目標的數字

[英]Finding the closest number in a Binary Tree to a given target

我有一個非常簡單的二叉樹

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)

我實現了一個 function 來找到樹中最接近目標的數字(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。令人驚訝的是,當我打印以下所有“最接近”的數字時,function 似乎工作正常:它打印:8、14、22。但它為什么不返回最近最近的數字:22?

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

第一次調用最接近的值時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

您沒有使用遞歸調用的結果來確定最終的返回值。

也許一種更簡單的方法,而不按下默認參數會更容易:

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) 方法,它將 go 通過整個二叉樹而不利用層次結構。 要獲得 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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM