Katkat

Find linked user records by weighted similarity

StripeSoftware Engineer · Technical Screen

Last updated

This problem tests your ability to model relationships as a graph and compute connected components based on weighted similarity scores between user records.

Problem Statement

You are given a list of user objects, where each object contains a unique id, a name, and an email. Two users are considered 'linked' if their similarity score meets or exceeds a given threshold T. The similarity score is calculated as follows:

  • +0.6 points if the email fields are identical.
  • +0.4 points if the name fields are identical.

Your task is to group all users into 'clusters' where a cluster is defined as a set of users connected directly or indirectly (e.g., if A is linked to B, and B is linked to C, then A, B, and C are in the same cluster).

Function Signature

def find_user_clusters(users, threshold) -> List[List[str]]

Constraints

  • users: List of dicts with id (int), name (str), email (str).
  • threshold: float (0.0 to 1.0).
  • Number of users: up to 10,000.
  • Return a list of lists, where each inner list contains the ids of users in that cluster.

Example

Input:

users = [
    {"id": 1, "name": "Alice", "email": "[email protected]"},
    {"id": 2, "name": "Alice", "email": "[email protected]"},
    {"id": 3, "name": "Bob", "email": "[email protected]"}
]
threshold = 0.4

Output: [[1, 2, 3]] Explanation:

  • (1, 2) have same name: score 0.4. Since 0.4 >= 0.4, they are linked.
  • (2, 3) have same email: score 0.6. Since 0.6 >= 0.4, they are linked.
  • By transitivity, all three are in the same cluster.

Edge Cases

  • Empty input list.
  • Threshold > 1.0 (no users should be linked).
  • Users with no shared attributes.

Hints

Hint 1

Treat each user as a node in a graph and establish edges between users whose similarity score meets the threshold.

Hint 2

Use a Disjoint Set Union (DSU) data structure or a Graph Traversal (DFS/BFS) algorithm to group connected nodes.

Hint 3

To optimize, group users by email and name first to avoid comparing every pair (O(N^2) complexity).

Follow-up questions

  • How would your solution change if the number of users grew to 10 million, making an N^2 comparison infeasible?
  • What if the similarity calculation became more complex, such as using Levenshtein distance for names instead of exact matches?
  • How would you handle a scenario where 'linked' status is time-dependent (e.g., an email address is only valid during specific date ranges)?