Implement Text Layout and Query Parsing
AirbnbSoftware Engineer · Technical ScreenLast updated
Implement URL query parameter extraction and a greedy text line-wrapper that enforces maximum line length and prevents orphan words on the final line.
Problem Statement
Airbnb listing titles and descriptions must be rendered dynamically across various web and mobile layouts. You are tasked with implementing a function that extracts layout parameters from a URL request and formats the display text into wrapped lines.
Your task is to write a function format_query_text(url: str) -> list[str] that performs two operations:
-
URL Query Parsing:
- Extract the query parameters following the
?character in theurl. - Key-value pairs are separated by
&, and keys are separated from values by=. If a key has no value or=is omitted, treat its value as an empty string. - Decode spaces in values: replace occurrences of
+and%20with a single space' '. - Extract
text(the text string to wrap) andwidth(an integer maximum line width). Ifwidthis missing or not a valid positive integer, default to20. Iftextis missing or empty, return an empty list[].
- Extract the query parameters following the
-
Text Layout & Wrapping:
- Split
textinto words by whitespace. - Pack words greedily into lines such that each line contains as many words as possible without its total character count (including single spaces between words) exceeding
width. - Any trailing punctuation attached to a word (e.g.,
"cabin,"or"view!") is treated as part of that word. - Orphan Prevention: If the resulting layout produces more than one line and the final line contains only a single word, rebalance the last two lines if possible. Specifically, move the last word from the second-to-last line to the beginning of the final line, provided that:
- The second-to-last line had at least 2 words prior to the move, and
- The new final line does not exceed
width. - If moving the word would exceed
width, leave the layout as-is.
- Split
Interface
def format_query_text(url: str) -> list[str]:
pass
Input & Output
- Input:
url: str- a URL string possibly containing query parameters. - Output:
list[str]- a list of lines representing the wrapped text.
Constraints
1 <= len(url) <= 10005 <= width <= 100- You may assume every individual word has a length less than or equal to
width. - No built-in URL parsing libraries (such as
urllib.parse) should be used; implement parsing manually.
Examples
Example 1
url = "https://airbnb.com/search?text=Cozy+cabin+in+the+woods&width=10"
output = format_query_text(url)
# Output: ["Cozy cabin", "in", "the woods"]
Explanation:
- Parameters extracted:
text = "Cozy cabin in the woods",width = 10. - Greedy wrapping gives:
["Cozy cabin", "in the", "woods"]. - The last line has only 1 word (
"woods"). The preceding line has 2 words ("in the"). Moving"the"down creates"the woods"(length 9 <= 10), leaving"in"on the second-to-last line.
Example 2
url = "https://airbnb.com/rooms?text=Quiet%20loft&width=20"
output = format_query_text(url)
# Output: ["Quiet loft"]
Explanation:
- Parameters:
text = "Quiet loft",width = 20. - Both words fit within width 20 on a single line.
Hints
Hint 1
Isolate query parsing first by splitting at '?' and '&', and remember to replace both '+' and '%20' with standard space characters.
Hint 2
Perform a standard greedy packing pass using a list of words per line before considering line-balancing adjustments.
Hint 3
Check the orphan condition only on the final line: inspect whether len(lines[-1]) == 1 and len(lines[-2]) >= 2, then calculate if moving the word satisfies the width constraint.
Follow-up questions
- How would you handle full percent-decoding (e.g., %2C for commas or %2F for slashes) without external libraries?
- How could this layout algorithm be modified to support full justification (evenly distributing spaces between words)?
- If orphan prevention was required for all lines (preventing any line from having fewer than two words, where possible), how would you structure the dynamic programming or search approach?
Solution walkthrough is for members
Get the full walkthrough with reference code and complexity analysis, plus Kitty Coach at 300 messages a day. Hints, the code runner and community answers stay free.