Coding questions · Meta
Sort a string by custom order
This interview question evaluates algorithm design, data structures, correctness, complexity, edge cases, and implementation details in a realistic interview setting. A strong answer for Sort a string by custom order states assumptions, handles edge cases, explains trade-offs, and shows how to validate the result clearly.
Given a priority string P of distinct characters and a text string S, reorder S so that all characters appearing in P come first and are grouped in the exact order specified by P, followed by all characters not in P while preserving their original relative order. Return the reordered string. Design an O(|P| + |S|) algorithm and discuss space usage. How would you adapt the solution for Unicode and for case-insensitive ordering?
What a Strong Answer Covers
- A clear algorithm with the right data structures and enough pseudocode or code-level detail to implement it.
- A correctness argument that explains why the algorithm covers all required cases.
- Time and space complexity, plus at least one alternative approach when relevant.
- Focused tests for normal cases, edge cases, and failure modes.
Follow-up Questions
- How would the approach change if the input were streaming or too large for memory?
- What invariants would you assert in production code?
- Which tests would catch off-by-one, duplicate, or tie-breaking bugs?
Sort a String by Custom Order
Given a priority string P of distinct characters and a text string S, reorder S so that:
- All characters of
Sthat appear inPcome first, grouped together in the exact order specified byP(all occurrences ofP[0], then all occurrences ofP[1], and so on). - They are followed by all characters of
Sthat do NOT appear inP, preserving their original relative order fromS.
Return the reordered string.
Characters in P are guaranteed distinct. Characters may repeat in S. Aim for an O(|P| + |S|) time algorithm.
Example 1
P = "cba", S = "abcd"
Output: "cbad"
Characters 'a','b','c' all appear in P, so they are ordered as c, b, a. 'd' is not in P, so it comes last.
Example 2
P = "kqep", S = "pekeq"
Output: "kqeep"
Counts: k=1, q=1, e=2, p=1. Emit in P order: k, q, e, e, p.
Example 3
P = "ba", S = "aabbcc"
Output: "bbaacc"
'b' before 'a' per P; 'c' not in P keeps its trailing order.
Constraints
- Characters in P are distinct.
- S may contain repeated characters.
- Either P or S may be empty.
- If P is empty, return S unchanged.
- Characters of S not in P must preserve their original relative order.
Hints
- Build a hash set (or map) of the characters in P so you can test membership in O(1).
- Single pass over S: count occurrences of each character that is in P, and append (in order) characters that are not in P to a separate buffer.
- Emit the result by walking P once and writing each character as many times as it was counted, then append the not-in-P buffer.
- For Unicode: iterate over code points (Python str already does; in Java/C++ decode UTF-8/UTF-16 to code points) rather than bytes, and key the count map by code point. For case-insensitive ordering, normalize both P and the matched characters with a consistent case fold before comparing, but emit the original characters.
Solution
Solution Alignment
The prompt asks for an implementation-level answer. The safest way to present it is to define the state, maintain clear invariants, then walk through complexity and tests.
Problem Restatement
Given a priority string P of distinct characters and a text string S, reorder S so that all characters appearing in P come first and are grouped in the exact order specified by P, followed by all characters not in P while preserving their original relative order. Return the reordered string. Design an O(|P| + |S|) algorithm and discuss space usage. How would you adapt the solution for Unicode and for case-insensitive ordering?
Recommended Approach
Use the string constraints to choose between two pointers, a stack, frequency counts, prefix/suffix state, or dynamic programming. Maintain the invariant that processed characters have already been normalized, counted, or matched according to the operation.
Correctness
The implementation should maintain an invariant after each loop or operation that directly matches the problem statement. At termination, that invariant implies the returned value has considered every valid candidate exactly once, or has preserved the required data-structure state after every API call.
Complexity
Most direct string scans are O(n) time. Space ranges from O(1) for two pointers to O(n) for stacks, maps, or DP tables.
Edge Cases and Tests
Empty string, length 1, repeated characters, invalid characters, case sensitivity, Unicode vs ASCII, and very long input.