AlgoMaster Logo

Chapter 11: Edge Case Checklist

16 min readUpdated March 30, 2026
Listen to this chapter
Unlock Audio

Chapter 11: Edge Case Checklist

You solve the problem. Your algorithm handles the main example perfectly. You trace through it, everything checks out. You feel great.

Then the interviewer says: "What if the input is empty?"

And suddenly you realize your code accesses nums[0] on the very first line. Your solution, which felt rock solid thirty seconds ago, crashes for the simplest possible input.

This happens constantly. Not because candidates are careless, but because human brains are wired to think about the "happy path" first. We naturally imagine typical inputs: arrays with several elements, strings with real characters, trees with multiple nodes. The edge cases, the weird, minimal, extreme inputs, require deliberate effort to consider.

This chapter gives you a systematic checklist to catch those cases before they catch you. Not a vague "think about edge cases" reminder, but a concrete list organized by data type that you can mentally run through for any problem.

Why Edge Cases Deserve Special Attention

There are two reasons edge cases matter disproportionately in interviews.

First, they are where bugs hide. Your algorithm's core logic might be perfect for arrays of length 10, but it falls apart for length 0 or 1. Off-by-one errors only surface at boundaries. Overflow only happens at extreme values. These are the cases that separate working code from correct code.

Second, interviewers specifically test for them. After you present a solution, a common follow-up is "What about this input?" followed by an edge case. If your code handles it gracefully, you look thorough. If it crashes, you look sloppy, even if the core algorithm was brilliant.

The good news is that edge cases are highly predictable. The same types of tricky inputs show up across hundreds of different problems. Learn the patterns once, and you can apply them everywhere.

Arrays

Arrays are the most common input type in coding interviews, and they have the most edge cases. Here is the full list to check:

Edge CaseWhy It MattersExample
Empty array []Crashes code that accesses nums[0] or assumes length > 0nums = []
Single element [x]Loops may not execute, two-pointer approaches need at least 2nums = [5]
Two elementsMinimum for pair-based operations, check boundary logicnums = [1, 2]
All identical valuesBreaks algorithms that assume distinct elementsnums = [3, 3, 3, 3]
Contains duplicatesAffects counting, deduplication, set-based approachesnums = [1, 2, 2, 3]
Already sorted (ascending)Best-case or worst-case depending on algorithmnums = [1, 2, 3, 4, 5]
Reverse sorted (descending)Worst case for many sorting-related approachesnums = [5, 4, 3, 2, 1]
Contains negativesAffects product calculations, max subarray, comparisonsnums = [-3, -1, 0, 2]
Contains zerosDivision by zero, product calculations, falsy checksnums = [0, 1, 0, 3]
Very large nTests time complexity, memory limitsn = 10^5 or 10^6

The Empty Array Trap

This one deserves special attention because it trips up so many people. Whenever your code has any of these patterns, ask yourself what happens when the array is empty:

The fix is usually a guard clause at the top:

The Single Element Trap

Single-element arrays break algorithms that compare adjacent elements, use two pointers starting at both ends, or rely on a loop executing at least once.

This might be fine depending on the problem, but you need to verify it explicitly.

The "All Same Values" Trap

This one is subtle. Many partition-based algorithms (quicksort, quickselect, three-way partitioning) degenerate when all values are identical. Your two pointers might never converge, or your partition step might put all elements on one side, turning O(n log n) into O(n^2).

Similarly, algorithms that look for "the first element different from X" will scan the entire array without finding anything. Always ask yourself: does my code terminate correctly when every element is the same?

Strings

Strings share many edge cases with arrays (they are, after all, arrays of characters), but they have a few unique concerns.

Edge CaseWhy It MattersExample
Empty string ""Length is 0, charAt(0) crashess = ""
Single character "a"Palindrome checks, substring operationss = "a"
All same charactersAffects frequency counting, pattern matchings = "aaaa"
Spaces and whitespacetrim() behavior, split edge casess = " hello "
Special charactersRegex issues, comparison edge casess = "a!@#b"
Unicode charactersLength counting, indexing differencess = "cafe\u0301"
Very long stringPerformance, stack overflow for recursive approachesn = 10^5
PalindromeEspecially if the problem involves string reversals = "racecar"
Case sensitivity"A" vs "a", depends on problem statements = "Hello"

The Empty String is Always Valid

For almost any string problem, the empty string is a valid input unless the problem explicitly says otherwise. Your code must handle it. A frequent mistake is to start processing characters without checking if there are any:

Case Sensitivity

Always clarify with the interviewer (or check the constraints) whether the input can contain uppercase and lowercase letters. If both are possible and the problem treats them the same, convert to one case early:

The Whitespace Minefield

Whitespace causes more trouble than most people expect. Consider String.split(" ") on the input " hello world ". In Java, this produces an array starting with empty strings. The behavior of split, trim, and strip differs across languages, so when strings can contain spaces, trace your code carefully with leading, trailing, and multiple consecutive spaces.

Numbers

Numeric inputs seem simple, but they harbor some of the trickiest bugs, especially around overflow and special values.

Edge CaseWhy It MattersExample
ZeroDivision by zero, multiplication identity, falsy in some languagesn = 0
Negative numbersAffects modular arithmetic, comparisons, absolute value logicn = -5
Integer overflowint max is ~2.1 billion, multiplication/addition can overflowa = 2000000000, b = 2000000000
Integer.MIN_VALUENegating it causes overflow: -(-2147483648) overflows intn = -2147483648
Very large valuesEven long has limits (~9.2 x 10^18)n = 10^18
OneMultiplicative identity, affects loop countsn = 1
Powers of 2Bit manipulation edge casesn = 1, 2, 4, 1024

Integer Overflow: The Silent Killer

This is the most dangerous numeric edge case because it does not crash your program. It just gives the wrong answer, silently. In Java and C++, integer overflow wraps around without any warning.

Another classic overflow scenario is computing the product of array elements or summing a large array. If the problem constraints say n can be up to 10^5 and values up to 10^4, the sum can reach 10^9, which is close to int max. Use long to be safe.

The Integer.MIN_VALUE Trap

In Java and C++, the range of int is not symmetric. The minimum value is -2,147,483,648 but the maximum is 2,147,483,647. Negating Integer.MIN_VALUE gives Integer.MIN_VALUE because 2,147,483,648 does not fit in an int. If your code ever negates an integer or takes its absolute value, this edge case can bite you.

Modular Arithmetic with Negatives

In Java, the % operator can return negative results for negative operands. This is a common surprise:

If your problem involves modular arithmetic and the input can be negative, always apply this correction.

Trees

Binary trees have a small but important set of edge cases.

Edge CaseWhy It MattersExample
Null/empty treeRoot is null, any access crashesroot = null
Single node (leaf only)No children, height is 0, it is its own answer for many queriesroot = [1]
Left-skewed treeBehaves like a linked list, O(n) height1 -> 2 -> 3 -> 4 (all left)
Right-skewed treeSame as above, but right children only1 -> 2 -> 3 -> 4 (all right)
Balanced treeBest case for height, O(log n)Standard BST
Tree with one child at each levelHeight equals n, worst case for recursive depthLinear chain
Duplicate valuesAffects BST search, comparison logicMultiple nodes with same value
Negative node valuesAffects sum calculations, path problemsNodes with value -1, -5

Null Root is Not Optional

Almost every tree problem should start with:

This is not just defensive programming. Many problems explicitly include the empty tree as a test case. Forgetting this check is an instant failure.

Skewed Trees Break Assumptions

If your algorithm assumes the tree is roughly balanced (height is O(log n)), a skewed tree turns it into O(n). This matters for recursive solutions because a skewed tree with 10^4 nodes means 10^4 levels of recursion, which can cause a stack overflow.

Both trees have 7 nodes, but the balanced tree has height 3 while the skewed tree has height 6. Your algorithm's correctness and performance should hold for both.

Negative Values in Path Problems

Many tree problems ask you to find maximum path sums, or check if a path with a certain sum exists. When node values can be negative, the logic changes. A path might exclude a subtree entirely because including it would decrease the sum. Make sure your code handles the case where the best answer is a negative number (for example, if all node values are negative).

Graphs

Graphs introduce structural edge cases that arrays and trees do not have.

Edge CaseWhy It MattersExample
Empty graph (0 nodes)No nodes to processn = 0, edges = []
Single node, no edgesTrivial case, often the base casen = 1, edges = []
Disconnected componentsBFS/DFS from one node misses othersTwo separate clusters
Self-loopsNode connects to itself, breaks visited checks if not carefulEdge (1, 1)
Parallel edges (multigraph)Multiple edges between same pairTwo edges from A to B
CyclesInfinite loops if visited not trackedA -> B -> C -> A
Fully connected (complete graph)O(V^2) edges, stress tests adjacency listEvery node connects to every other
Directed vs undirectedAffects neighbor traversal, cycle detectionCheck problem statement
Negative edge weightsBreaks Dijkstra, need Bellman-FordWeight = -3

Disconnected Graphs: The Silent Failure

Many candidates write BFS or DFS starting from node 0 and assume they will visit all nodes. If the graph is disconnected, you miss entire components. The fix is simple but easy to forget:

Cycles: The Infinite Loop

If your graph has cycles and you do not track visited nodes, your traversal will loop forever. This is basic, but under interview pressure, people sometimes forget to add the visited check, especially when converting from tree code (where cycles are impossible) to graph code.

Self-Loops and Parallel Edges

These are rarer in interview problems, but when they show up, they can break your solution in subtle ways. A self-loop means a node is its own neighbor. If your code processes all neighbors of a node, it will process the node itself, which can corrupt your visited state or counting logic. Always check whether the problem constraints allow self-loops, and if so, add a simple guard:

Linked Lists

Linked lists have their own set of tricky cases that are worth calling out separately, since pointer manipulation is where many interview bugs live.

Edge CaseWhy It MattersExample
Null headEmpty list, any access crasheshead = null
Single nodehead.next is null, algorithms that need two nodes break1 -> null
Two nodesMinimum for swap or reverse operations1 -> 2 -> null
Cycle in the listTraversal never terminates1 -> 2 -> 3 -> 2 (cycle)
Operation at headDeleting or inserting at head requires special handlingDelete first node
Operation at tailNeed to find the last node, or second-to-lastDelete last node

The Dummy Head Trick

Many linked list edge cases around the head node disappear if you use a dummy (sentinel) node:

This avoids separate logic for "what if we need to remove the head" or "what if the new node goes before the current head." It is a small technique that eliminates an entire class of bugs.

General Edge Cases

Some edge cases apply regardless of the specific data type.

Edge CaseWhy It MattersExample
Null inputNullPointerException in Java, undefined behavior in C++nums = null
Maximum constraint valuesTests if your solution meets the time/space complexityn = 10^5
Minimum constraint valuesTests boundary handlingn = 1
All elements satisfy conditionWhat if every element qualifies?All positive in "count positives"
No elements satisfy conditionWhat if nothing qualifies?No pairs sum to target
Result is zero or emptyReturn 0, empty list, or special value?No matching subarray
Large outputOutput itself might cause issues (list of all subsets)2^n subsets

How to Systematically Think About Edge Cases

Memorizing the tables above helps, but the real skill is developing a systematic way to generate edge cases for any problem. Here is a mental framework:

Step 1: Identify the input types. What are you given? An array? A string? A tree? Two arrays? A number and a matrix?

Step 2: For each input, go through its category above. Check the relevant table. Which cases apply to this problem?

Step 3: Think about the output. What happens when the answer is the minimum possible value? The maximum? Zero? Empty? What if there are multiple valid answers?

Step 4: Think about the algorithm. Where does your specific approach break? If you are using two pointers, what happens with fewer than 2 elements? If you are dividing, can the divisor be zero? If you are using recursion, can the depth be too large?

Step 5: Check the constraints. The problem's constraints often hint at edge cases. If it says "1 <= n <= 10^5", you know n = 1 is a valid edge case. If it says "0 <= nums[i] <= 10^9", you know zeros and large values are fair game.

Putting It Into Practice

Let us apply this checklist to a real problem. Say you are solving "Find the kth largest element in an array."

Input type: Array of integers, plus integer k.

Array edge cases to check:

  • Empty array: Can it happen? Usually not for this problem, but clarify.
  • Single element: k must be 1. Does your code handle this?
  • All identical values: The kth largest is the same as the 1st largest. Does your partitioning or sorting handle this?
  • Contains negatives: Does not affect most approaches, but verify.
  • Already sorted: Is this best case or worst case for your approach? (For quickselect with bad pivot selection, a sorted array is worst case.)

Number edge cases to check:

  • k = 1: The maximum. Trivial, but verify.
  • k = n: The minimum. Trivial, but verify.
  • k = n/2: Middle element, typical case.

Algorithm-specific check (quickselect):

  • What happens if the pivot selection is bad repeatedly? Consider the time complexity.
  • What if all elements are the same? Partitioning might degenerate.

Going through this checklist takes about 60 seconds. It could save you from a bug that costs you the entire interview.

Let us try one more. Say you are solving "Validate Binary Search Tree."

Input type: Binary tree.

Tree edge cases to check:

  • Null root: Should return true (an empty tree is a valid BST).
  • Single node: No children to violate the BST property. Returns true.
  • Left-skewed tree: Every node only has a left child. Is each left child strictly less than its parent?
  • Duplicate values: Does the problem consider duplicates valid? Usually not in a BST. Your comparison must use strict inequality.
  • Negative values: Your range bounds must account for negative values. If you initialize min/max with 0, that is a bug.

Algorithm-specific check (recursive range):

  • If you are passing min and max bounds, what initial values do you use? Integer.MIN_VALUE and Integer.MAX_VALUE? What happens if a node has value Integer.MIN_VALUE?

That last point is a real trap. If your initial lower bound is Integer.MIN_VALUE and the root node's value is also Integer.MIN_VALUE, your comparison node.val > min fails, and you incorrectly reject a valid BST. The fix is to use Long.MIN_VALUE and Long.MAX_VALUE, or use null to represent "no bound."

Summary

Edge cases are not mysterious. They follow predictable patterns based on the input type. The key is having a checklist and the discipline to use it every time, not just when you remember.

The core habit: after writing your solution, spend 60 seconds running through the relevant edge case table for each input type. Ask yourself, "What happens when this input is empty? A single element? All the same? Maximum size?" If your code handles those cases, it almost certainly handles everything in between.

Here are the cases that trip up the most candidates, ranked by frequency:

  1. Empty input (array, string, tree, graph)
  2. Single element input
  3. Integer overflow in arithmetic operations
  4. Null/None input when the language allows it
  5. All identical values in a collection
  6. Disconnected components in graphs

Build the habit of checking these systematically, and edge cases stop being a source of anxiety. They become a source of confidence, because you know you have already thought about them.