Find best-matching binary pattern with wildcards
Company: Google
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: hard
Interview Round: Onsite
Quick Answer: This question evaluates pattern-matching and string-algorithm skills, including handling wildcards and variable-length matches, priority-based rule selection, and the design of preprocessing and query-time data structures.
Constraints
- 1 <= len(rules) <= 500
- 1 <= len(queries) <= 500
- 1 <= len(pattern) <= 500
- 0 <= len(query) <= 500
- Sum of all pattern lengths <= 2 * 10^4
- Sum of all query lengths <= 2 * 10^4
- Each pattern contains only '0', '1', '*', and '.'
- Each query contains only '0' and '1'
Examples
Input: ([('10*1', 'A'), ('0*', 'B'), ('*11', 'C')], ['10001', '01110', '111', '101'])
Expected Output: ['A', 'B', 'C', 'A']
Explanation: '10001' matches '10*1', '01110' matches '0*', '111' matches '*11', and '101' matches '10*1' with '*' taking the empty substring.
Input: ([('1.0', 'X'), ('10*', 'Y'), ('1*0', 'Z')], ['110', '1000'])
Expected Output: ['X', 'Y']
Explanation: For '110', both '1.0' and '1*0' match and both have length 3, so the earlier rule '1.0' wins. For '1000', both '10*' and '1*0' match with the same length, so the earlier rule '10*' wins.
Input: ([('.', 'ONE'), ('*', 'ANY'), ('0', 'ZERO')], ['', '0', '1'])
Expected Output: ['ANY', 'ONE', 'ONE']
Explanation: The empty string is matched only by '*'. For '0' and '1', both '.' and '*' match with length 1, so the earlier rule '.' wins.
Input: ([('1*0', 'SHORT'), ('1**0', 'LONGER'), ('1.0', 'DOT')], ['10', '110'])
Expected Output: ['LONGER', 'LONGER']
Explanation: Both '1*0' and '1**0' match these queries, but the original pattern '1**0' has length 4, so it beats '1*0' with length 3.
Input: ([('01', 'A'), ('1.1', 'B')], ['0', '1110'])
Expected Output: [None, None]
Explanation: Neither query fully matches any rule.
Hints
- If you sort rules by (-original_pattern_length, original_index), then the first rule that matches a query is automatically the correct answer.
- Use the classic greedy wildcard matcher with two pointers and the most recent '*' position. Treat '.' the same way you would treat a single-character wildcard.