Find longest unique substring
Company: Lowe's
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: Medium
Interview Round: Technical Screen
Quick Answer: This interview question evaluates algorithm design, data structures, correctness, complexity, edge cases, and implementation details in a realistic interview setting. A strong answer for Find longest unique substring states assumptions, handles edge cases, explains trade-offs, and shows how to validate the result clearly.
Constraints
- 0 <= len(s) <= 10^5
- s may contain any Unicode code points (ASCII letters, digits, symbols, spaces).
- Characters are compared by exact code-point equality (case-sensitive: 'A' != 'a').
- If s is empty, return [0, ""].
Examples
Input: ("abcabcbb",)
Expected Output: [3, "abc"]
Explanation: The first window of length 3 with all-unique chars is 'abc'; later windows like 'bca'/'cab' tie but the algorithm reports the first one found.
Input: ("bbbbb",)
Expected Output: [1, "b"]
Explanation: Every character repeats, so the longest unique substring is any single 'b' of length 1.
Input: ("pwwkew",)
Expected Output: [3, "wke"]
Explanation: The longest unique substring is the contiguous 'wke' (length 3); 'pwke' would be a subsequence, not a substring.
Input: ("",)
Expected Output: [0, ""]
Explanation: Empty-string edge case: length 0 with an empty example.
Input: ("a",)
Expected Output: [1, "a"]
Explanation: Single-character string is trivially unique.
Input: ("dvdf",)
Expected Output: [3, "vdf"]
Explanation: When 'd' repeats at index 2, the window restarts after the first 'd', yielding 'vdf' of length 3 rather than an incorrect 'dvdf'.
Input: ("abba",)
Expected Output: [2, "ab"]
Explanation: Boundary check: when the second 'a' appears, its previous index 0 is already left of the current window start, so the window is not shrunk incorrectly; the max length stays 2 ('ab').
Input: ("tmmzuxt",)
Expected Output: [5, "mzuxt"]
Explanation: After the repeated 'm', the window grows to 'mzuxt' (length 5); the trailing 't' was last seen before the window start, so it does not force a shrink.
Hints
- Use a sliding window with two pointers: a left boundary `start` and a right boundary `i` scanning the string.
- Keep a hash map from each character to the most recent index where you saw it. When the current character was last seen at index >= start, jump `start` to one past that index to drop the duplicate from the window.
- Track the best (longest) window length and its start index as you go, so you can slice out one example substring at the end. The left pointer never moves backward, which is why the whole scan is O(n).