JavaScriptで二分探索木(BST)内の最小絶対差を求める方法
問題の概要
数値データを格納した二分探索木(BST)のルートノードを受け取り、木に存在する任意の2つのノード間の絶対差の最小値を返すJavaScript関数を作成します。
例として、次のような二分探索木を考えてみましょう。
1 \ 3 / 2
この木に対する期待される出力は以下の通りです。
const output = 1;
これは |1 − 2| = |3 − 2| = 1 となるためです。
解法のポイント:中順走査の活用
二分探索木には「中順走査(In-order Traversal)を行うとノードの値が必ず昇順に並ぶ」という重要な性質があります。この性質を利用すれば、すべてのノードペアを総当たりで比較する必要はなく、昇順に並んだ値の隣接要素同士の差だけを調べればよいため、計算量を O(n) に抑えることができます。
実装例
class Node{
constructor(data) {
this.data = data;
this.left = null;
this.right = null;
};
};
class BinarySearchTree{
constructor(){
// 二分探索木のルート
this.root = null;
}
insert(data){
var newNode = new Node(data);
if(this.root === null){
this.root = newNode;
}else{
this.insertNode(this.root, newNode);
};
};
insertNode(node, newNode){
if(newNode.data < node.data){
if(node.left === null){
node.left = newNode;
}else{
this.insertNode(node.left, newNode);
};
} else {
if(node.right === null){
node.right = newNode;
}else{
this.insertNode(node.right,newNode);
};
};
};
};
const BST = new BinarySearchTree();
BST.insert(1);
BST.insert(3);
BST.insert(2);
const getMinimumDifference = function(root) {
const nodes = [];
const dfs = (root) => {
if(root) {
dfs(root.left);
nodes.push(root.data);
dfs(root.right);
};
};
dfs(root);
let result = nodes[1] - nodes[0];
for(let i = 1; i < nodes.length - 1; i++) {
result = Math.min(result, nodes[i + 1] - nodes[i]);
};
return result;
};
console.log(getMinimumDifference(BST.root));
出力結果
コンソールには次のように表示されます。
1
コードの解説
まず、Node クラスで各ノードの構造(値・左の子・右の子)を定義し、BinarySearchTree クラスでノードを挿入するメソッドを実装しています。
核心となる getMinimumDifference 関数では、再帰的な DFS(深さ優先探索)による中順走査でノードの値を訪問順に配列 nodes へ格納します。中順走査によって配列は昇順にソートされた状態になるため、あとは隣接する2要素の差を順に比較し、その最小値を Math.min で更新していくだけで答えが得られます。
-
Pythonで二分探索木の最小共通祖先(LCA)を求める方法【再帰アルゴリズム解説】
最小共通祖先(LCA)とは二分探索木(Binary Search Tree)が与えられたとき、指定された2つのノードの最小共通祖先(Lowest Common Ancestor:LCA)を求める問題を考えてみましょう。ノード p と q の LCA とは、「p と q の両方を子孫として持つノードの中で、最も深い位置にあるノード」のことです。例えば、次のような二分木があるとします。[6, 2, 8, 0, 4, 7, 9, null, null, 3, 5]この木は以下のような構造になります。この場合、2 と 8 の LCA は 6 となります。6 は 2 と 8 の両方を子孫に持ち、それより
-
Pythonでソート済み配列を高さバランスの二分探索木に変換する方法
ソートされた配列 A が与えられたとき、そこから高さバランスの取れた二分探索木(BST)を生成することを考えます。ここで「高さバランスの取れた二分木」とは、すべてのノードにおいて、左右の部分木の深さの差が常に1以下であるような二分木のことを指します。例として、配列が [-10, -3, 0, 5, 9] の場合、出力の一例は [0, -3, 9, -10, null, 5] のようになります。解法のアプローチこの問題は、配列の中央要素をルートに選ぶというシンプルな発想で解くことができます。具体的な手順は以下の通りです。配列 A が空の場合は、Null(None)を返します。配列の中央の要素を見