diff --git a/CMakeLists.txt b/CMakeLists.txt index 0c6c48d6..921db68f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -691,6 +691,7 @@ add_task(valid-perfect-square) add_task(valid-sudoku) add_task(valid-triangle-number) add_task(validate-binary-search-tree) +add_task(validate-binary-tree-nodes) add_task(validate-stack-sequences) add_task(verifying-an-alien-dictionary) add_task(water-and-jug-problem) diff --git a/solutions/validate-binary-tree-nodes/CMakeLists.txt b/solutions/validate-binary-tree-nodes/CMakeLists.txt new file mode 100644 index 00000000..d8f9b5a5 --- /dev/null +++ b/solutions/validate-binary-tree-nodes/CMakeLists.txt @@ -0,0 +1 @@ +add_catch(test_validate_binary_tree_nodes test.cpp) diff --git a/solutions/validate-binary-tree-nodes/solution.hpp b/solutions/validate-binary-tree-nodes/solution.hpp new file mode 100644 index 00000000..942dac32 --- /dev/null +++ b/solutions/validate-binary-tree-nodes/solution.hpp @@ -0,0 +1,52 @@ +#pragma once + +#include + +class DisjointSets { +public: + explicit DisjointSets(int size) : parents_(size), count_(size) { + for (int i = 0; i < size; ++i) { + parents_[i] = i; + } + } + + int Count() { return count_; } + + int Parent(int i) { + if (parents_[i] != i) { + parents_[i] = Parent(parents_[i]); + } + return parents_[i]; + } + + bool Merge(int parent, int child) { + if (child != Parent(child) || Parent(child) == Parent(parent)) { + return false; + } + + --count_; + parents_[Parent(child)] = Parent(parent); + return true; + } + +private: + std::vector parents_; + int count_; +}; + +class Solution { +public: + static bool validateBinaryTreeNodes(int n, const std::vector &left, + const std::vector &right) { + DisjointSets sets(n); + for (const auto &children : {left, right}) { + for (int parent = 0; parent < n; ++parent) { + const auto child = children[parent]; + if (child != -1 && !sets.Merge(parent, child)) { + return false; + } + } + } + return sets.Count() == 1; + } +}; diff --git a/solutions/validate-binary-tree-nodes/test.cpp b/solutions/validate-binary-tree-nodes/test.cpp new file mode 100644 index 00000000..d6ae46d2 --- /dev/null +++ b/solutions/validate-binary-tree-nodes/test.cpp @@ -0,0 +1,45 @@ +#include + +#include + +TEST_CASE("Simple") { + struct TestCase { + int n; + std::vector leftChild; + std::vector rightChild; + bool expected; + }; + + std::vector test_cases{ + { + .n = 4, + .leftChild{1, -1, 3, -1}, + .rightChild{2, -1, -1, -1}, + .expected = true, + }, + { + .n = 4, + .leftChild{1, -1, 3, -1}, + .rightChild{2, 3, -1, -1}, + .expected = false, + }, + { + .n = 2, + .leftChild{1, 0}, + .rightChild{-1, -1}, + .expected = false, + }, + { + .n = 4, + .leftChild{1, 0, 3, -1}, + .rightChild{-1, -1, -1, -1}, + .expected = false, + }, + }; + + for (const auto &[n, leftChild, rightChild, expected] : test_cases) { + const auto actual = + Solution::validateBinaryTreeNodes(n, leftChild, rightChild); + REQUIRE(expected == actual); + } +}