Minimize Inversions in a Prefix Tree - Solution & Explanation
Problem Statement
You are given an array words of n unique strings containing only lowercase English letters from 'a' to 'j'. You are also given an integer array target containing each index from 0 to n - 1 exactly once.
Build a prefix tree from words:
- The root represents the empty string
"". - Each other node represents a different non-empty prefix of a word. The parent of a node is the prefix obtained by removing its last character.
- The node representing the complete word
words[i]is marked with indexi. A marked node may also have children.
You may choose the order of the children of each node independently. You cannot change which node is a child's parent.
Traverse the tree starting at the root. When visiting a node, first record its index if it is marked. Then visit its children in the chosen order, completing the traversal of each child before moving to the next. This is a pre-order traversal.
The recorded indices form an array traversal of length n. Let pos[i] be the position of index i in target.
An inversion is a pair of positions (a, b) such that 0 <= a < b < n and pos[traversal[a]] > pos[traversal[b]].
Return the minimum possible number of inversions over all choices of child orderings.
Example 1:
āāāāāāāāāāāāāāāāāāāāā
Input: words = ["bad","bag","fig","fed"], target = [3,1,0,2]
Output: 2
Explanation:
Visit the root's "f" child before its "b" child. Within the "f" branch, visit "fed" before "fig". Within the "b" branch, visit "bag" before "bad".
This produces traversal = [3,2,1,0]:
| Traversal position | Word index | Word | Position in target |
|---|---|---|---|
| 0 | 3 | "fed" |
0 |
| 1 | 2 | "fig" |
3 |
| 2 | 1 | "bag" |
1 |
| 3 | 0 | "bad" |
2 |
The positions in target are [0,3,1,2]. The inversions are the pairs of traversal positions (1,2) and (1,3), since 3 > 1 and 3 > 2.
No child ordering produces fewer than 2 inversions.
Example 2:
Input: words = ["ab","ac","ba","bc"], target = [0,3,1,2]
Output: 1
Explanation:
Visit the root's "a" child before its "b" child. Within these branches, visit "ab" before "ac", and "bc" before "ba".
This produces traversal = [0,1,3,2]:
| Traversal position | Word index | Word | Position in target |
|---|---|---|---|
| 0 | 0 | "ab" |
0 |
| 1 | 1 | "ac" |
2 |
| 2 | 3 | "bc" |
1 |
| 3 | 2 | "ba" |
3 |
The positions in target are [0,2,1,3]. The only inversion is the pair of traversal positions (1,2), since 2 > 1.
No child ordering produces zero inversions.
Constraints:
1 <= n == words.length <= 1041 <= words[i].length <= 20words[i]contains only lowercase English letters from'a'to'j'āāāāāāā- All
words[i]are unique 0 <= target[i] <= n - 1targetis a permutation of integers from 0 ton - 1
Approach Overview
Problem Overview: You get a prefix tree (trie) where each node's children can be reordered. Each reordering changes the sequence of values read off the tree, and you want the arrangement that produces the fewest inversions, meaning pairs that appear out of order.
Approach 1: Brute Force Over All Child Orderings (Exponential)
Enumerate every permutation of children at every node, build the resulting sequence, and count inversions with a nested loop. The number of arrangements grows as the product of factorials of child counts, so this is only useful for checking small inputs. It runs in O(k! * n^2) time and O(n) space, where k is the largest branching factor. Use it to validate a faster solution on tiny test cases, not as a submission.
Approach 2: Recursive Greedy with Pairwise Inversion Counts (O(n^2))
Process the tree bottom-up with DFS. For each node, compute the sequence produced by each child subtree and the cross-inversions between every pair of children, in both possible orders. Then pick the order that yields fewer cross-inversions. The key insight is that choices at different nodes are independent, so a local greedy decision at each node gives a global optimum. Count cross-inversions with nested loops over the child sequences. This is simpler to reason about than the optimal version, and it is fast enough for moderate inputs. Time is O(n^2) in the worst case and space is O(n) for the recursion and stored sequences.
Approach 3: Greedy DFS with Merge-Based Inversion Counting (Optimal, O(n log n))
Keep the same bottom-up greedy idea, but replace the nested loops with a merge step from merge sort. Each subtree returns its sorted sequence along with an inversion count. When merging two child sequences, one merge pass counts how many elements from the left child exceed elements from the right child, which gives both cross-inversion totals in linear time. Swap the children only when the swapped order gives fewer cross-inversions, then merge. Total time is O(n log n) and space is O(n). Prefer this approach whenever the input is large, because the nested-loop version hits its limit quickly.
Recommended for interviews: Interviewers expect you to state the brute force, then justify the greedy per-node choice, and finally implement the merge-based counting. The brute force shows you understand the search space. The greedy argument and the merge-based count show you can cut it down to O(n log n). Explain why independent subtree choices compose correctly before you write any code.
Related topics: tree, divide and conquer, sorting.
Solutions for this problem are being prepared.
Try solving it yourselfDetailed Complexity Analysis
| Approach | Time | Space | When to Use |
|---|---|---|---|
| Brute Force (all orderings) | O(k! * n^2) | O(n) | Validating answers on tiny inputs |
| Greedy with nested loop counts | O(n^2) | Moderate inputs, easier to reason about | |
| Greedy DFS with merge counting | O(n log n) | General case, large inputs, interview answer |
Video Solution
4075. Minimize Inversions in a Prefix Tree (Leetcode Hard)
Frequently Asked Questions
Is Minimize Inversions in a Prefix Tree easy or hard?
How to solve Minimize Inversions in a Prefix Tree in O(n log n)?
What is the best approach for Minimize Inversions in a Prefix Tree?
What data structure is used in Minimize Inversions in a Prefix Tree?
What is the time complexity of Minimize Inversions in a Prefix Tree?
Minimize Inversions in a Prefix Tree Python solution: how do I write it?
Is Minimize Inversions in a Prefix Tree asked at Google, Amazon, or Meta?
Ready to solve this problem?
Practice Minimize Inversions in a Prefix Tree with our built-in code editor and test cases.
Practice on FleetCodeProblem Info
Table of Contents
Practice this problem
Open in Editor