4
unique_ptr<Node> right;12
left = make_unique<Node>();19
right = make_unique<Node>();26
return !left && !right;30
constexpr static const int ModBase = 1'000'000'007;32
/// the number of ways to interleave two sequences of length x and y33
/// respectively. this feels like very similar to combinations C(x+y, x).34
static int interleaves(int x, int y) {35
static int memo[1001][1001] = {-123};36
if (memo[0][0] == -123) {37
// initialize the memo elements to non-zero,38
// because zero can be a valid value after the modulo op.39
memset(memo, -1, sizeof(memo));41
// todo: or just compute this table bottom-up.42
if (x == 0 || y == 0) {48
if (memo[x][y] != memo[0][0]) {51
return memo[x][y] = (interleaves(x - 1, y) + interleaves(x, y - 1)) % ModBase;54
/// return a tuple which represents <CountOfNodes, Combinations>55
tuple<int, int> traverseNode(Node *node) {63
auto [leftNodeCount, leftCombos] = traverseNode(node->left.get());65
auto [rightNodeCount, rightCombos] = traverseNode(node->right.get());66
int totalCombos = ((int64_t)leftCombos * rightCombos) % ModBase;67
totalCombos = ((int64_t)totalCombos * interleaves(leftNodeCount, rightNodeCount)) % ModBase;68
return {1 + leftNodeCount + rightNodeCount, totalCombos};69
} else { // right side is empty70
return {1 + leftNodeCount, leftCombos};72
} else { // left side is empty, but it must have the right side, because74
auto [rightNodeCount, rightCombos] = traverseNode(node->right.get());75
return {1 + rightNodeCount, rightCombos};80
int numOfWays(vector<int> &nums) {82
auto root = make_unique<Node>();84
for (int i = 1; i < nums.size(); ++i) {85
root->insert(nums[i]);88
auto [nodeCount, combos] = traverseNode(root.get());