Resolve routing-number to bank mapping
Company: Plaid
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: easy
Interview Round: Technical Screen
Quick Answer: This question evaluates a candidate's skills in data normalization, deduplication, aggregation, and conflict resolution across multiple JSON data sources, with emphasis on canonicalization of aliases and handling inconsistent mappings.
Part 1: Normalize Routing-Number Bank Mappings
Constraints
- 0 <= len(records) <= 100000
- 0 <= total number of alias strings across all banks <= 100000
- Each record contains keys 'routing_number' and 'bank_name'
- Routing numbers should be treated as strings in the output
- After normalization, alias groups do not overlap
Examples
Input: ([{'routing_number': '111000025', 'bank_name': ' Bank of America '}, {'routing_number': '111000025', 'bank_name': 'BOFA'}, {'routing_number': '021000021', 'bank_name': ' chase '}, {'routing_number': '021000021', 'bank_name': 'JPMORGAN CHASE'}], {'Bank of America': ['BOFA', 'B.O.A.', 'Bank of america'], 'Chase': ['JPMorgan Chase', 'JP Morgan Chase']})
Expected Output: {'111000025': 'Bank of America', '021000021': 'Chase'}
Explanation: Both records for 111000025 resolve to Bank of America, and both records for 021000021 resolve to Chase after case-insensitive normalization and alias matching.
Input: ([{'routing_number': '111', 'bank_name': 'alpha bank'}, {'routing_number': '111', 'bank_name': 'Beta Bank'}, {'routing_number': '111', 'bank_name': ' ALPHA BANK '}], {'Alpha Bank': ['Alpha bank'], 'Beta Bank': ['beta bank']})
Expected Output: {'111': 'CONFLICT'}
Explanation: The same routing number resolves to Alpha Bank and Beta Bank, so the final value must be CONFLICT. Once conflicted, it stays conflicted.
Hints
- Build one reverse hash map from every known alias to its canonical bank name before processing the records.
- For each routing number, remember the first resolved bank. If a later resolved bank is different, mark that routing number as a conflict.
Part 2: Resolve Routing Numbers Across Multiple Data Sources
Constraints
- 0 <= len(sources) <= 10000
- The total number of records across all sources is at most 100000
- Each source contains keys 'source', 'weight', and 'records'
- Each weight is a positive integer
- After normalization, alias groups do not overlap
Examples
Input: ([[('111', ' Bank of America '), ('111', 'boa')], [('111', 'Bank of America')]], [2, 1], {'boa': 'Bank of America'})
Expected Output: {'111': 'Bank of America'}
Explanation: In the first source, both names normalize to Bank of America, so that source casts one vote worth 2. The second source adds another vote worth 1. Bank of America wins with total weight 3.
Input: ([[('222', 'Chase'), ('222', ' JP Morgan Chase ')], [('222', 'Wells Fargo')], [('222', ' chase ')]], [3, 4, 2], {'jp morgan chase': 'Chase'})
Expected Output: {'222': 'Chase'}
Explanation: Source 1 contributes 3 to Chase because both records are equivalent after alias normalization. Source 2 contributes 4 to Wells Fargo. Source 3 contributes 2 to Chase. Final totals: Chase 5, Wells Fargo 4.
Hints
- Resolve duplicates and contradictions inside each source before doing any cross-source voting.
- Use a nested hash map like routing -> bank -> total score to accumulate weighted votes.