Phonebook shelf tree
MediumOnline Assessment
Arrange the names in a phone directory app as a binary search tree that needs the fewest comparisons.
The app stores n distinct names in sorted order, numbered 0 to n - 1, in a binary search tree: every name in a node's left subtree sorts before it, every name in its right subtree sorts after it. You choose the shape of the tree.
Every day people look up names. hits[i] is how many times name i is searched for and found. misses[j] is how many searches are for a name that is not stored and that sorts after name j - 1 and before name j (misses[0] is before name 0, misses[n] is after the last name).
A search starts at the root and compares the searched name with the node it is at, one comparison per node visited, going left or right until it finds the name or falls off the tree. A hit on a node at depth d (the root has depth 1) costs d comparisons. A miss costs the number of nodes it visited before falling off the tree, which is the depth of the last node on its path. With no names at all, a search visits no nodes and costs 0.
Input: hits, the daily hit count for each name, and misses, the daily counts of misses by gap.
Output: the smallest possible total number of comparisons per day over all valid trees.
There are far too many tree shapes to try each one, even for 40 names.
Example 1
- Input:
- [[5],[3,2]]
- Output:
- 10
- Explanation
- With one stored name the tree is a single node. Every hit (5 of them) and every miss (3 + 2 of them) costs exactly one comparison: 5 + 3 + 2 = 10.
Example 2
- Input:
- [[10,1],[4,0,3]]
- Output:
- 22
- Explanation
- Rooting the tree at name 0 costs 10 comparisons for its hits, 4 for the misses before it, and puts name 1 at depth 2: 1 x 2 for its hit plus 3 x 2 for the misses after it, with the 0 misses in between adding nothing. Total 10 + 4 + 2 + 6 = 22. Rooting at name 1 instead costs more.
Example 3
- Input:
- [[2,3,2],[8,6,0,1]]
- Output:
- 37
- Explanation
- The most-searched name is name 1, but the best root is name 0, because 14 misses pile up before name 1. Root 0, then name 1 below it on the right, then name 2 below that: hits cost 2 x 1 + 3 x 2 + 2 x 3 = 14, and misses cost 8 x 1 + 6 x 2 + 0 x 3 + 1 x 3 = 23. The total is 37.
Constraints
0 <= hits.length <= 120misses.length == hits.length + 10 <= hits[i], misses[i] <= 1,000