CATEGORY 11 OF 13

Edge Cases & Parsing

Learn to handle input validation, boundary conditions, null/empty checks, string parsing, type coercion pitfalls, and overflow — the defensive coding skills that separate robust solutions from fragile ones.

Time: Varies by problem — validation is typically O(n) for input of size n
Space: O(1) to O(n) depending on parsing approach

Learn & Reference

Understanding the Pattern

Edge Cases & Parsing

Writing code that works for the happy path is easy. Writing code that handles every weird, broken, or unexpected input is what separates solid engineers from the rest. Edge case handling and input parsing are skills you will use in every single interview problem, even if the problem itself is not "about" parsing.

Input Validation Patterns

Before processing any input, ask yourself: what could go wrong?

  • Empty or null input — what does your function return for "", null, undefined, or nil?
  • Single element — does your algorithm work when the input has exactly one character, one element, or one digit?
  • Whitespace — does leading, trailing, or excessive internal whitespace break your parser?
  • Unexpected characters — what happens when letters appear where digits are expected, or vice versa?

Boundary Conditions

Off-by-one errors and boundary conditions are the most common source of bugs in interviews:

  • Off-by-one — is your loop bound < or <=? Does your index start at 0 or 1?
  • Empty input — the string is "", the array is [], the number is 0
  • Single element — only one character, one item, one digit
  • Maximum/minimum values — 32-bit integer overflow (2^31 - 1 = 2147483647, -2^31 = -2147483648)
  • Negative numbers — does your code handle the sign correctly?

String-to-Number Parsing

Converting strings to numbers is deceptively tricky:

  1. Skip leading whitespace" 42" should parse as 42
  2. Handle optional sign"+42" and "-42" are both valid
  3. Stop at first non-digit"42abc" should parse as 42
  4. Overflow clamping — results outside the 32-bit range must be clamped

Type Coercion Pitfalls

Different languages handle type coercion differently:

  • JavaScript: "" == false is true, "0" == false is true, null == undefined is true
  • Python: empty string is falsy, 0 is falsy, empty list is falsy
  • Java: Integer.parseInt() throws NumberFormatException on invalid input
  • Go: strconv.Atoi() returns an error (no exceptions)

Integer Overflow Handling

In languages with fixed-width integers (Java, Go, C++), arithmetic can silently overflow:

  • 32-bit signed range: -2,147,483,648 to 2,147,483,647
  • Check before multiplying: if result > MAX / 10, the next result * 10 + digit will overflow
  • Python exception: Python integers have arbitrary precision — no overflow, but interview problems often ask you to enforce 32-bit limits

Whitespace & Formatting Edge Cases

  • Leading/trailing whitespace — always trim unless the problem says otherwise
  • Multiple consecutive spaces — should they collapse to one? Or be preserved?
  • Tabs, newlines, carriage returns — are these "whitespace" in your context?
  • Empty string after trimming — trimming " " gives ""

Common Mistakes

  1. Not handling empty input: forgetting to check for empty strings or null values before processing, leading to index-out-of-bounds or null pointer errors
  2. Ignoring leading/trailing whitespace: many inputs have hidden whitespace that breaks comparisons and parsing
  3. Off-by-one in boundary checks: using >= instead of > when checking overflow, or starting a loop at the wrong index
  4. Silent overflow in Java/Go/C++: multiplying or adding without checking if the result exceeds the 32-bit range first
  5. Forgetting the negative sign: parsing "-42" but only handling digits, losing the sign
  6. Case sensitivity in string comparisons: "True" vs "true" vs "TRUE" — normalize before comparing
  7. Not stopping at invalid characters: continuing to parse after encountering a non-digit character when building a number
  8. Assuming well-formed input: real interview inputs include empty strings, single characters, all-whitespace strings, and garbage data

When to Use

Convert a string to a number (atoi, parseInt)
Validate whether input matches a format (emails, numbers, versions)
Handle boundary conditions (empty, single element, overflow)
Parse structured text (CSV, version strings, key-value pairs)
Normalize or clean user input (whitespace, casing)
Compare formatted values (version numbers, IP addresses)
Extract data from unstructured strings (numbers from text)
Any problem where the description mentions edge cases or invalid input

Template

1# --- Safe Parse with Default ---
2def safe_parse_int(s, default=0):
3 try:
4 return int(s.strip())
5 except (ValueError, AttributeError):
6 return default
7
8# --- Character-by-Character Parsing ---
9def parse_digits(s):
10 i = 0
11 # Skip whitespace
12 while i < len(s) and s[i] == ' ':
13 i += 1
14 # Handle sign
15 sign = 1
16 if i < len(s) and s[i] in '+-':
17 sign = -1 if s[i] == '-' else 1
18 i += 1
19 # Parse digits
20 result = 0
21 while i < len(s) and s[i].isdigit():
22 result = result * 10 + int(s[i])
23 i += 1
24 return result * sign
25
26# --- Validate Input Before Processing ---
27def process(s):
28 if not s or not s.strip():
29 return None # handle empty/whitespace
30 s = s.strip()
31 # ... process cleaned input
{ }

Syntax Reference

1# === String Parsing ===
2int("42") # string to int: 42 (raises ValueError on invalid)
3float("3.14") # string to float: 3.14
4str(42) # int to string: "42"
5s.strip() # trim whitespace
6s.lstrip() # trim left only
7s.rstrip() # trim right only
8s.isdigit() # all digits? (no sign, no decimal)
9s.isnumeric() # numeric chars? (broader than isdigit)
10s.isalpha() # all letters?
11s.isalnum() # letters or digits?
12
13# === Safe Parsing ===
14try:
15 val = int(s)
16except ValueError:
17 val = 0 # default on failure
18
19# === Regex ===
20import re
21re.findall(r'-?\d+', s) # find all integers (with optional negative)
22re.match(r'^[+-]?\d+$', s) # match entire string as integer
23re.sub(r'\s+', ' ', s) # collapse whitespace
24
25# === Overflow Constants ===
26INT_MAX = 2**31 - 1 # 2147483647
27INT_MIN = -(2**31) # -2147483648
📋

Common Recipes

1# --- Safe String to Integer (atoi) ---
2def safe_atoi(s):
3 s = s.strip()
4 if not s:
5 return 0
6 sign = 1
7 i = 0
8 if s[i] in '+-':
9 sign = -1 if s[i] == '-' else 1
10 i += 1
11 result = 0
12 while i < len(s) and s[i].isdigit():
13 result = result * 10 + int(s[i])
14 i += 1
15 result *= sign
16 return max(-(2**31), min(2**31 - 1, result))
17
18# --- Validate Number Format ---
19def is_number(s):
20 s = s.strip()
21 if not s:
22 return False
23 i = 0
24 if s[i] in '+-':
25 i += 1
26 has_digit = False
27 has_dot = False
28 while i < len(s):
29 if s[i].isdigit():
30 has_digit = True
31 elif s[i] == '.' and not has_dot:
32 has_dot = True
33 else:
34 return False
35 i += 1
36 return has_digit
37
38# --- Compare Version Strings ---
39def compare_versions(v1, v2):
40 parts1 = list(map(int, v1.split('.')))
41 parts2 = list(map(int, v2.split('.')))
42 n = max(len(parts1), len(parts2))
43 for i in range(n):
44 a = parts1[i] if i < len(parts1) else 0
45 b = parts2[i] if i < len(parts2) else 0
46 if a < b: return -1
47 if a > b: return 1
48 return 0
O(n)

Complexity

OperationTimeNotes
String to integer (atoi)O(n)Single pass through digits
Number validationO(n)Single pass through characters
Whitespace normalizationO(n)Scan and rebuild string
Overflow detectionO(n)Check during digit parsing
Regex matchingO(n)Linear for simple patterns
Version comparisonO(n)n = total length of both strings
Email validationO(n)Single pass with state tracking

Watch Out

  • Not handling empty input: forgetting to check for empty strings or null values before processing, leading to index-out-of-bounds or null pointer errors
  • Ignoring leading/trailing whitespace: many inputs have hidden whitespace that breaks comparisons and parsing
  • Off-by-one in boundary checks: using `>=` instead of `>` when checking overflow, or starting a loop at the wrong index
  • Silent overflow in Java/Go/C++: multiplying or adding without checking if the result exceeds the 32-bit range first
  • Forgetting the negative sign: parsing `"-42"` but only handling digits, losing the sign
  • Case sensitivity in string comparisons: `"True"` vs `"true"` vs `"TRUE"` — normalize before comparing
  • Not stopping at invalid characters: continuing to parse after encountering a non-digit character when building a number
  • Assuming well-formed input: real interview inputs include empty strings, single characters, all-whitespace strings, and garbage data