Keep Stable Unique Column Names Across Schema Changes
Company: Microsoft
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: medium
Interview Round: Onsite
Return stable effective column names for repeated snapshots of table schemas. Replace every dot in an original column name with an underscore. Effective names must be unique within a table, ignoring ASCII case. Resolve collisions with suffixes `_1`, `_2`, and so on.
Implement `rename_columns(calls: string[][]) -> string[][]`. Each input row is `[tableName, column1, column2, ...]` and describes that table's current ordered column list. Return one array of effective column names per call, in the same order as its columns.
### Constraints & Assumptions
- At most 1000 calls and 10000 column occurrences in total. Names contain ASCII letters, digits, dots, and underscores and are nonempty; each name is at most 100 characters.
- Table identity and original column identity use exact case-sensitive strings. No original column is repeated within a single call. Different original names differing only in case remain different columns and need distinct effective names.
- Each table maintains an independent persistent mapping for all original names ever seen during this function call. Once assigned, an effective name never changes, even if the column disappears, moves, or later returns.
- Effective names assigned to absent columns remain reserved. This reservation policy makes the reported reappearance guarantee explicit.
- Process newly encountered columns in their input order. The initial candidate is the original name with dots replaced by underscores. If its case-insensitive form is reserved, try that entire candidate plus `_1`, then `_2`, and so on, choosing the first unused suffix. Preserve the candidate's original case in the assigned name.
- Natural suffixes are ordinary name text. For example, a new original `a_1` whose candidate is already reserved may become `a_1_1`, not automatically `a_2`.
- Calls and returned arrays may contain zero columns.
### Example
```text
calls = [["T","a.b","a_b","a_b_1"],
["T","a_b"],
["T","a_b_1","a.b","A.B"],
["U","a_b"]]
result = [["a_b","a_b_1","a_b_1_1"],
["a_b_1"],
["a_b_1_1","a_b","A_B_2"],
["a_b"]]
```
Explain why rebuilding names from only the current snapshot breaks stability, and how you handle a natural suffixed name colliding with an earlier generated name. Analyze repeated collision searches rather than assuming every new assignment is constant time.
```hint Keep identity and reservation separate
The original-to-effective mapping preserves historical identity. A second case-normalized set answers whether a candidate effective name is already reserved for that table.
```
Overview: Maintain stable case-insensitive unique column names across additions, removals, reordering, reappearance, and natural suffix collisions, with independent table histories.
Read the full Microsoft Software Engineer interview experience this question came from