A kingdom consists of a king, his children, his grandchildren, and so on. Every once in a while, someone in the family dies or a child is born.
The kingdom has a well-defined order of inheritance that consists of the king as the first member. Let's define the recursive function Successor(x, curOrder)
, which given a person x
and the inheritance order so far, returns who should be the next person after x
in the order of inheritance.
Successor(x, curOrder):
if x has no children or all of x's children are in curOrder:
if x is the king return null
else return Successor(x's parent, curOrder)
else return x's oldest child who's not in curOrder
Implement the ThroneInheritance
class:
ThroneInheritance(string kingName)
Initializes an object of the ThroneInheritance
class. The name of the king is given as part of the constructor.void birth(string parentName, string childName)
Indicates that parentName
gave birth to childName
.void death(string name)
Indicates the death of name
. The death of the person doesn't affect the Successor
function nor the current inheritance order. You can treat it as just marking the person as dead.string[] getInheritanceOrder()
Returns a list representing the current order of inheritance excluding dead people.Example:
Input
["ThroneInheritance", "birth", "birth", "birth", "birth", "birth", "birth", "getInheritanceOrder", "death", "getInheritanceOrder"]
[["king"], ["king", "andy"], ["king", "bob"], ["king", "catherine"], ["andy", "matthew"], ["bob", "alex"], ["bob", "asha"], [null], ["bob"], [null]]
Output
[null, null, null, null, null, null, null, ["king", "andy", "matthew", "bob", "alex", "asha", "catherine"], null, ["king", "andy", "matthew", "alex", "asha", "catherine"]]
Explanation
ThroneInheritance t= new ThroneInheritance("king"); // order: king
t.birth("king", "andy"); // order: king > andy
t.birth("king", "bob"); // order: king > andy > bob
t.birth("king", "catherine"); // order: king > andy > bob > catherine
t.birth("andy", "matthew"); // order: king > andy > matthew > bob > catherine
t.birth("bob", "alex"); // order: king > andy > matthew > bob > alex > catherine
t.birth("bob", "asha"); // order: king > andy > matthew > bob > alex > asha > catherine
t.getInheritanceOrder(); // return ["king", "andy", "matthew", "bob", "alex", "asha", "catherine"]
t.death("bob"); // order: king > andy > matthew > bob > alex > asha > catherine
t.getInheritanceOrder(); // return ["king", "andy", "matthew", "alex", "asha", "catherine"]
Design and implement the ThroneInheritance
class with the specified methods.
## Throne Inheritance Problem Solution
This problem requires implementing a data structure that maintains the order of inheritance in a kingdom, considering births and deaths. The key is efficiently managing the family tree and generating the inheritance order, skipping dead members.
### 1. Naive (Brute Force) Solution
A simple approach is to maintain the family tree using a dictionary or a similar data structure where each person maps to their children. The `getInheritanceOrder` function would then perform a Depth-First Search (DFS) on the tree, starting from the king, and collect the living members in the order they are visited.
#### Implementation Details:
* **Data Structure**: Use a dictionary/map to store the tree, where keys are person names, and values are lists of their children.
* **Birth**: Add the child to the parent's list of children.
* **Death**: Mark the person as dead using a separate set or a flag in the tree node.
* **getInheritanceOrder**: Perform DFS, adding only living members to the result.
#### Code (Python):
```python
class ThroneInheritance:
def __init__(self, kingName: str):
self.king = kingName
self.children = {}
self.dead = set()
def birth(self, parentName: str, childName: str):
if parentName not in self.children:
self.children[parentName] = []
self.children[parentName].append(childName)
def death(self, name: str):
self.dead.add(name)
def getInheritanceOrder(self):
order = []
self.dfs(self.king, order)
return order
def dfs(self, person, order):
if person not in self.dead:
order.append(person)
if person in self.children:
for child in self.children[person]:
self.dfs(child, order)
birth
: O(1)death
: O(1)getInheritanceOrder
: O(N), where N is the number of people in the kingdom.dead
set.The above solution is already quite efficient, but the key is to ensure that the DFS in getInheritanceOrder
is as streamlined as possible.
set
for dead
provides O(1) lookup for dead members.parentName
is guaranteed to be alive for each call to birth
, so we don't need to handle cases where the parent doesn't exist.ThroneInheritance
: O(1)birth
: O(1)death
: O(1)getInheritanceOrder
: O(N), where N is the number of people in the kingdom.dead
set.The solution maintains a tree structure representing the kingdom's family tree and a set to keep track of dead members. The getInheritanceOrder
function performs a DFS to generate the inheritance order, excluding dead members. The time complexity is dominated by the DFS, which is O(N), and the space complexity is O(N) to store the tree and dead set.