Quick Overview

Filter structured logs by an ordered minimum severity, preserving threshold-and-higher records while handling empty and unknown levels under an explicit contract.

Filter Logs by an Ordered Severity Threshold

Role: Software Engineer

Category: Coding & Algorithms

Difficulty: medium

Interview Round: Onsite

Filter log records using a minimum severity level. A threshold includes that level and every higher level; it is not a keyword search in the message. Implement `filter_logs(levels: string[], minimum: string, logs: string[][]) -> string[][]`. ### Constraints & Assumptions - Levels lists unique nonempty severity names from lowest to highest. There are at most 100 levels; minimum is one of them. - Each log is either an empty array (an empty record) or `[level,message]`. A missing level is represented by the empty string. Unknown or missing levels and empty records are dropped; this handling is an explicit practice policy where the source asks for tests but does not state the outcome. - A known qualifying level with an empty message is retained. Message contents never change the record's severity. - Preserve record order and duplicate occurrences. Return each retained two-string record unchanged. - At most 200000 logs and 2000000 total string characters. ### Example ```text levels = ["DEBUG","INFO","WARN","ERROR"] minimum = "WARN" logs = [["INFO","contains WARN text"],["WARN","slow"], ["ERROR",""],[],["","missing"],["OTHER","unknown"]] result = [["WARN","slow"],["ERROR",""]] ``` Explain why checking the string for the word WARN is incorrect and how the ordered-level model represents the intended requirement. Include exact-threshold, higher/lower-level, missing-level, empty-record, and empty-message cases in your test plan. ```hint Severity belongs to the structured field Map level names to their position in the supplied ordering. The free-text message is unrelated to that comparison. ```

Overview: Filter structured logs by an ordered minimum severity, preserving threshold-and-higher records while handling empty and unknown levels under an explicit contract.

Read the full Software Engineer interview experience this question came from

Filter log records using a minimum severity level. A threshold includes that level and every higher level; it is not a keyword search in the message. Implement `filter_logs(levels: string[], minimum: string, logs: string[][]) -> string[][]`. ### Constraints & Assumptions - Levels lists unique nonempty severity names from lowest to highest. There are at most 100 levels; minimum is one of them. - Each log is either an empty array (an empty record) or `[level,message]`. A missing level is represented by the empty string. Unknown or missing levels and empty records are dropped; this handling is an explicit practice policy where the source asks for tests but does not state the outcome. - A known qualifying level with an empty message is retained. Message contents never change the record's severity. - Preserve record order and duplicate occurrences. Return each retained two-string record unchanged. - At most 200000 logs and 2000000 total string characters. ### Example ```text levels = ["DEBUG","INFO","WARN","ERROR"] minimum = "WARN" logs = [["INFO","contains WARN text"],["WARN","slow"], ["ERROR",""],[],["","missing"],["OTHER","unknown"]] result = [["WARN","slow"],["ERROR",""]] ``` Explain why checking the string for the word WARN is incorrect and how the ordered-level model represents the intended requirement. Include exact-threshold, higher/lower-level, missing-level, empty-record, and empty-message cases in your test plan. ```hint Severity belongs to the structured field Map level names to their position in the supplied ordering. The free-text message is unrelated to that comparison. ```

Constraints

  • Levels contains at most 100 unique nonempty names from lowest to highest; minimum is a listed name.
  • At most 200000 logs and 2000000 total string characters.
  • Each record is [] or [level,message]. Drop empty records and unknown or missing levels.
  • Retain known levels at or above the threshold even with empty messages; message contents do not affect severity.
  • Return retained records unchanged, preserving original order and duplicates.

Examples

Input: (['DEBUG', 'INFO', 'WARN', 'ERROR'], 'WARN', [['INFO', 'contains WARN text'], ['WARN', 'slow'], ['ERROR', ''], [], ['', 'missing'], ['OTHER', 'unknown']])

Expected Output: [['WARN', 'slow'], ['ERROR', '']]

Explanation: Structured severity, not message keywords, determines retention.

Input: (['HIGH', 'LOW'], 'LOW', [['HIGH', 'LOW'], ['LOW', 'plain'], ['LOW', 'plain']])

Expected Output: [['LOW', 'plain'], ['LOW', 'plain']]

Explanation: Supplied order overrides conventional names and preserves duplicate rows.

Loading coding console...

Show the approach

Approach

Map each supplied severity name to its index and resolve the minimum index once. For every record in original order, discard an empty row or a level absent from the map; otherwise retain it exactly when its index is at least the threshold. Because severity names are nonempty, the missing-level empty string is automatically unknown. The message is never inspected, so empty messages survive at qualifying levels and a low-severity message mentioning WARN does not become a warning. Appending original qualifying rows preserves order and duplicate occurrences. With L levels and N logs, expected work is O(L+N) dictionary operations plus level-name hashing and output copying. Auxiliary state is O(L) entries excluding output; C++ copies retained records into the result while the other versions can retain row references.

Time complexity:
O(L + N) expected lookups plus string hashing and output copying
Space complexity:
O(L) rank entries, excluding output