public static function getSequences(BinaryTreeNode $node) { $prefix = [$node->getData()]; $left = $node->getLeft(); $right = $node->getRight(); if ($left === null && $right === null) { return [$prefix]; } $leftSequences = $left !== null ? self::getSequences($left) : null; $rightSequences = $right !== null ? self::getSequences($right) : null; $sequences = []; if ($leftSequences === null) { foreach ($rightSequences as $rightSequence) { $sequences[] = array_merge($prefix, $rightSequence); } return $sequences; } if ($rightSequences === null) { foreach ($leftSequences as $leftSequence) { $sequences[] = array_merge($prefix, $leftSequence); } return $sequences; } // combine $leftSequences and $rightSequences in every possible way foreach ($leftSequences as $leftSequence) { foreach ($rightSequences as $rightSequence) { $mergedSequence = array_merge($leftSequence, $rightSequence); $orderings = self::getAllOrderings($mergedSequence); foreach ($orderings as $ordering) { $sequences[] = array_merge($prefix, $ordering); } } } return $sequences; }
public static function isBinarySearchTree(BinaryTreeNode $node, $min = null, $max = null) { $left = $node->getLeft(); $right = $node->getRight(); $nodeValue = $node->getData(); if ($left !== null) { $leftValue = $left->getData(); if ($nodeValue < $leftValue) { return false; } if ($min !== null && $min > $leftValue) { return false; } if (!self::isBinarySearchTree($left, $min, $nodeValue)) { return false; } } if ($right !== null) { $rightValue = $right->getData(); if ($nodeValue > $rightValue) { return false; } if ($max !== null && $max < $rightValue) { return false; } if (!self::isBinarySearchTree($right, $nodeValue, $max)) { return false; } } return true; }
public function testBinaryTreeNode() { $node1 = new BinaryTreeNode('Dizzy'); $this->assertEquals('Dizzy', $node1->getData()); $this->assertEquals('Dizzy', (string) $node1); $node1->setData('Miles'); $this->assertEquals('Miles', $node1->getData()); $this->assertEquals('Miles', (string) $node1); $this->assertNull($node1->getLeft()); $this->assertNull($node1->getRight()); $node2 = new BinaryTreeNode('Cannonball'); $node3 = new BinaryTreeNode('Coltrane'); $node1->setLeft($node2); $node1->setRight($node3); $this->assertSame($node2, $node1->getLeft()); $this->assertSame($node3, $node1->getRight()); }
public static function countPathsWithSum(BinaryTreeNode $node, $targetSum, array $breadCrumb = []) { $newBreadCrumb = array_merge($breadCrumb, [$node->getData()]); $resultCount = self::getPathSumCount($newBreadCrumb, $targetSum); $left = $node->getLeft(); if ($left !== null) { $resultCount += self::countPathsWithSum($left, $targetSum, $newBreadCrumb); } $right = $node->getRight(); if ($right !== null) { $resultCount += self::countPathsWithSum($right, $targetSum, $newBreadCrumb); } return $resultCount; }
public static function countPathsWithSum(BinaryTreeNode $node = null, $targetSum, $runningSum = 0, array &$pathCountMap = []) { if ($node === null) { return 0; } $runningSum += $node->getData(); $sum = $runningSum - $targetSum; $totalPaths = array_key_exists($sum, $pathCountMap) ? $pathCountMap[$sum] : 0; if ($runningSum === $targetSum) { $totalPaths++; } $pathCountMap[$runningSum] = (array_key_exists($runningSum, $pathCountMap) ? $pathCountMap[$runningSum] : 0) + 1; $totalPaths += self::countPathsWithSum($node->getLeft(), $targetSum, $runningSum, $pathCountMap); $totalPaths += self::countPathsWithSum($node->getRight(), $targetSum, $runningSum, $pathCountMap); $pathCountMap[$runningSum] -= 1; return $totalPaths; }
public static function getMaxDepthOrNegativeOneIfUnbalanced(BinaryTreeNode $node = null) { if ($node === null) { return 0; } $leftDepth = self::getMaxDepthOrNegativeOneIfUnbalanced($node->getLeft()); if ($leftDepth == -1) { return -1; } $rightDepth = self::getMaxDepthOrNegativeOneIfUnbalanced($node->getRight()); if ($rightDepth == -1) { return -1; } if (abs($leftDepth - $rightDepth) > 1) { return -1; } return max($leftDepth, $rightDepth) + 1; }
protected static function findFirstCommonAncestorResult(BinaryTreeNode $node, BinaryTreeNode $p, BinaryTreeNode $q) { $isP = $node === $p; $isQ = $node === $q; $left = $node->getLeft(); $right = $node->getRight(); $leftIsP = false; $leftIsQ = false; $leftResult = null; if ($left !== null) { $leftResult = self::findFirstCommonAncestorResult($left, $p, $q); $leftReturnNode = $leftResult !== null ? $leftResult->getNode() : null; $leftIsP = $leftReturnNode === $p; $leftIsQ = $leftReturnNode === $q; if ($isP && $leftIsQ || $isQ && $leftIsP) { return new CommonAncestorResult($node, 2); } } $rightIsP = false; $rightIsQ = false; $rightResult = null; if ($right !== null) { $rightResult = self::findFirstCommonAncestorResult($right, $p, $q); $rightReturnNode = $rightResult !== null ? $rightResult->getNode() : null; $rightIsP = $rightReturnNode === $p; $rightIsQ = $rightReturnNode === $q; if ($isP && $rightIsQ || $isQ && $rightIsP) { return new CommonAncestorResult($node, 2); } } if ($leftIsP && $rightIsQ || $leftIsQ && $rightIsP) { return new CommonAncestorResult($node, 2); } if ($leftResult !== null) { return $leftResult; } elseif ($rightResult !== null) { return $rightResult; } elseif ($isP || $isQ) { $coverCount = ($isP ? 1 : 0) + ($isQ ? 1 : 0); return new CommonAncestorResult($node, $coverCount); } return null; }