Loud and Rich - Solution & Explanation
Problem Statement
There is a group of n people labeled from 0 to n - 1 where each person has a different amount of money and a different level of quietness.
You are given an array richer where richer[i] = [ai, bi] indicates that ai has more money than bi and an integer array quiet where quiet[i] is the quietness of the ith person. All the given data in richer are logically correct (i.e., the data will not lead you to a situation where x is richer than y and y is richer than x at the same time).
Return an integer array answer where answer[x] = y if y is the least quiet person (that is, the person y with the smallest value of quiet[y]) among all people who definitely have equal to or more money than the person x.
Example 1:
Input: richer = [[1,0],[2,1],[3,1],[3,7],[4,3],[5,3],[6,3]], quiet = [3,2,5,4,6,1,7,0] Output: [5,5,2,5,4,5,6,7] Explanation: answer[0] = 5. Person 5 has more money than 3, which has more money than 1, which has more money than 0. The only person who is quieter (has lower quiet[x]) is person 7, but it is not clear if they have more money than person 0. answer[7] = 7. Among all people that definitely have equal to or more money than person 7 (which could be persons 3, 4, 5, 6, or 7), the person who is the quietest (has lower quiet[x]) is person 7. The other answers can be filled out with similar reasoning.
Example 2:
Input: richer = [], quiet = [0] Output: [0]
Constraints:
n == quiet.length1 <= n <= 5000 <= quiet[i] < n- All the values of
quietare unique. 0 <= richer.length <= n * (n - 1) / 20 <= ai, bi < nai != bi- All the pairs of
richerare unique. - The observations in
richerare all logically consistent.
Approach Overview
Problem Overview: You are given a list of richer relationships where richer[i] = [a, b] means person a is richer than b. For every person x, return the person who is the quietest among everyone who has at least as much money as x (including themselves).
Approach 1: Graph Representation and DFS with Memoization (Time: O(n + m), Space: O(n + m))
The relationships naturally form a directed graph. If a is richer than b, then b can reach a when searching for richer people. Build an adjacency list where each node points to people who are richer than it. For every person, run a DFS to explore all reachable richer nodes and track the index with the smallest quiet value. Memoization stores the result for each node so the DFS for that person runs only once. This avoids recomputation and keeps the complexity linear in the number of people and edges.
This approach works well because each node's answer depends only on nodes above it in the "richer" hierarchy. DFS combined with caching effectively turns the graph into a dynamic programming problem over a graph. The recursion explores richer neighbors, compares quietness values, and propagates the best candidate back to the caller. Using memoization ensures each node's quietest richer person is computed a single time.
Approach 2: Topological Sort Based Approach (Time: O(n + m), Space: O(n + m))
Another way to view the problem is information propagation along a DAG. If a is richer than b, the quietest candidate for a could influence the answer for b. Build edges from richer to poorer and compute indegrees. Start with nodes that have no richer prerequisites and process them using a topological order.
During traversal, propagate the quietest known person along outgoing edges. If the quietest person reachable from a is quieter than the current candidate for b, update b's answer. This continues until all nodes are processed. Because the graph is processed once in topological order, the total runtime stays linear. This approach highlights the problem as a dependency flow across a topological sort in a directed graph.
Recommended for interviews: The DFS with memoization solution is the most commonly expected approach. It clearly shows understanding of depth-first search, graph traversal, and caching overlapping subproblems. The topological sort solution is equally optimal but slightly less intuitive at first glance. Showing the DFS solution quickly and mentioning the topological alternative demonstrates strong graph problem-solving skills.
Approach 1: Graph Representation and DFS with Memoization
This approach involves representing the problem as a directed graph, where each edge indicates that one person is richer than another. We perform a Depth-First Search (DFS) from each node to find the quietest person that can potentially reach the given node using memoization to optimize the search process.
We create a directed graph where each node is a person and there is an edge u -> v if u is richer than v. We then perform a DFS from each node to determine the quietest person reachable starting from that node. The memoization helps in storing previously computed answers to avoid redundant calculations.
Code
Python
JavaScript
Java
C++
C#
Complexity
Time Complexity: O(n + e), where n is the number of people and e is the number of relationships. Each node and edge is processed once.
Space Complexity: O(n + e), to store the graph and the answer array.
Approach 2: Topological Sort Based Approach
This approach involves using topological sorting to process the nodes in an order where each node processes its neighbors only after it has been considered. This sorts the nodes such that for any richer pair a -> b, 'a' appears before 'b'. We then traverse the graph to determine the quietest person for each node.
We first construct a graph and calculate in-degrees for each node. Using a queue (BFS approach), nodes with zero in-degree are processed first, ensuring an order where a richer person is processed before the one richer than them. For each node, update the answer to maintain the quietest reachable person using the quiet array.
Code
Python
Complexity
Time Complexity: O(n + e), as each node and edge is processed.
Space Complexity: O(n + e), due to storing the graph and in-degrees.
Approach 3: Default Approach
Code
Python
Java
C++
Go
TypeScript
Complexity Comparison
| Approach | Complexity |
|---|---|
| Graph Representation and DFS with Memoization | Time Complexity: O(n + e), where n is the number of people and e is the number of relationships. Each node and edge is processed once. |
| Topological Sort Based Approach | Time Complexity: O(n + e), as each node and edge is processed. |
| Default Approach | — |
Detailed Complexity Analysis
| Approach | Time | Space | When to Use |
|---|---|---|---|
| Graph DFS with Memoization | O(n + m) | O(n + m) | General case. Best when exploring richer relationships recursively with caching. |
| Topological Sort Propagation | O(n + m) | O(n + m) | Useful when modeling the problem as dependency flow in a DAG. |
Video Solution
Leetcode 851 | Loud and Rich | DFS | Graph • Hellgeek Arena • 7,178 views views
Watch 9 more video solutions →Frequently Asked Questions
Is Loud and Rich easy or hard?
How to solve Loud and Rich in O(n)?
What is the best approach for Loud and Rich?
What data structure is used in Loud and Rich?
What is the time complexity of Loud and Rich?
Loud and Rich Python or Java solution approach
Is Loud and Rich asked at Google, Amazon, or Meta?
Ready to solve this problem?
Practice Loud and Rich with our built-in code editor and test cases.
Practice on FleetCode