簡體   English   中英

二叉搜索樹遍歷 - 查找最接近的值

[英]Binary Search Tree traversal - Find Closest Value

我正在處理一個 AlgoExpert 挑戰,我已經花時間自己解決它,觀看了關於它的視頻講座,我覺得我有一個很好的理解,但是我的遞歸和樹遍歷技能現在相當低(這就是為什么我在做這個工作)。

這是提示

編寫一個 function,它接受二叉搜索樹 (BST) 和目標 integer 值,並返回與 BST 中包含的目標值最接近的值。 每個 BST 節點都有一個 integer、一個子節點和一個子節點。 它的子節點本身是有效的 BST 節點或None / Null

目標:12

到目前為止,這是我的解決方案:

function findClosestValueInBst(tree, target) {
    let closest = tree.value;
  const traverse = (inputTree) => {
        if (inputTree === null) return;
        if (Math.abs(target - closest) > Math.abs(target - inputTree.value)) {
            closest = inputTree.value;
        }
        
        if (target < tree.value) {
            console.log('left')
            traverse(inputTree.left)
        } else {
            console.log('right')
            traverse(inputTree.right)
        }
        
    }
    traverse(tree)
    return closest;
}

// This is the class of the input tree. Do not edit.
class BST {
  constructor(value) {
    this.value = value;
    this.left = null;
    this.right = null;
  }
}

到目前為止的行為是,遍歷到節點 15,但隨后,它沒有轉到 13,而是轉到 22,因此它返回 10 作為關閉的可能值,而不是絕對值更接近 12 的 13,而不是 10。

function findClosestValueInBst(tree, target) {
    let closest = tree.value;
  const traverse = (inputTree) => {
        if (inputTree === null) return;
        if (Math.abs(target - closest) > Math.abs(target - inputTree.value)) {
            closest = inputTree.value;
        }
        // As you can see below this line you are checking target < tree.value
        // problem is that tree is the root that your surrounding function gets
        // not the argument that your recursive function gets.
        // both your condition and your parameter to traverse
        // need to be inputTree, not tree
        if (target < tree.value) {
            console.log('left')
            traverse(inputTree.left)
        } else {
            console.log('right')
            traverse(inputTree.right)
        }
        
    }
    traverse(tree)
    return closest;
}

現在看下面的代碼:

function findClosestValueInBst(root, target) {
    let closest = root.value;
  const traverse = (node) => {
        if (node === null) return;
        if (Math.abs(target - closest) > Math.abs(target - node.value)) {
            closest = node.value;
        }
        
        if (target < node.value) {
            console.log('left')
            traverse(node.left)
        } else {
            console.log('right')
            traverse(node.right)
        }
        
    }
    traverse(root)
    return closest;
}

在這種情況下,將參數命名得更加明確是有幫助的,這樣就不會產生混淆。

也許這行得通。

它檢查單個 function 中的節點,並使用具有較大初始值的最后一個值。

然后它查找是否找到目標並返回目標。

否則檢查目標是否在里面

 function findClosestValue(tree, target, last = tree.value) { if (tree === null) return last; if (tree.value === target) return target; if ( last < target && target < tree.value || tree.value < target && target < last ) return Math.abs(target - this.value) < Math.abs(target - last)? this.value: last; return target < tree.value? findClosestValue(tree.left, target, tree.value): findClosestValue(tree.right, target, tree.value); } const tree = { value: 10, left: { value: 7, left: { value: 5, left: null, right: null }, right: { value: 8, left: null, right: null } }, right: { value: 13, left: { value: 11, left: null, right: null }, right: { value: 15, left: null, right: null } } }; console.log(findClosestValue(tree, 11)); console.log(findClosestValue(tree, 12)); console.log(findClosestValue(tree, 13)); console.log(findClosestValue(tree, 14)); console.log(findClosestValue(tree, 15)); console.log(findClosestValue(tree, 16)); console.log(tree);
 .as-console-wrapper { max-height: 100%;important: top; 0; }

使用 Nina Scholz 的測試用例,但我認為這是一個更簡單的遞歸,我們可以這樣做:

 const closer = (v) => (x, y) => Math.abs (x - v) < Math.abs (y - v)? x: y const findClosestValueInBst = (node, target) => node == null? Infinity: target == node.value? node.value: target < node.value? closer (target) (findClosestValueInBst (node.left, target), node.value): closer (target) (findClosestValueInBst (node.right, target), node.value) const tree = { value: 10, left: { value: 7, left: { value: 5, left: null, right: null }, right: { value: 8, left: null, right: null } }, right: { value: 13, left: { value: 11, left: null, right: null }, right: { value: 15, left: null, right: null } } }; console.log (findClosestValueInBst (tree, 11)) console.log (findClosestValueInBst (tree, 12)) console.log (findClosestValueInBst (tree, 13)) console.log (findClosestValueInBst (tree, 14)) console.log (findClosestValueInBst (tree, 15)) console.log (findClosestValueInBst (tree, 16)) console.log (tree)
 .as-console-wrapper {max-height: 100%;important: top: 0}

closer的助手只是選擇兩個數字中的哪個更接近目標,如果它們同樣接近,則任意選擇第二個。

如果提供的樹是null ,則主 function 簡單地以無限值轉義,然后根據我們的target是否等於、小於或大於當前節點的值進行分支。 如果equal ,我們就完成並返回節點的值。 如果less than ,我們在左分支上遞歸,然后選擇該結果和節點值中最接近的那個,類似地,如果greater than ,我們對右分支做同樣的事情。

請注意,我的答案可能與 Nina 的不同,因為我們對1113是否更接近12做出了不同的任意選擇。

暫無
暫無

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

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