TechInterviewPrep
Data Structures & Algorithms

Linked Lists

Singly/doubly linked lists, pointer manipulation, and the classic two-pointer patterns.

Topic: Data Structures & Algorithms · Subject: Programming Fundamentals · Roles: AI Engineer, Data Scientist, Software Engineer

What it is

A linked list is a sequence of nodes where each node holds a value and a pointer to the next node. Unlike an array, nodes are not stored contiguously in memory — they can be scattered anywhere, connected only by pointers.

Singly vs. doubly linked

  • Singly linked: each node points only to the next node. Simpler, less memory per node, but no backward traversal.
  • Doubly linked: each node also points to the previous node. Enables O(1) deletion given a direct node reference and backward traversal, at the cost of an extra pointer per node.

Complexity cheat sheet

OperationArrayLinked List
Access by indexO(1)O(n)
Insert/delete at headO(n)O(1)
Insert/delete in middle (with pointer)O(n)O(1)
SearchO(n)O(n)

The core trade-off: linked lists give up random access and cache locality in exchange for O(1) insertion/deletion when you already have a pointer to the right spot.

Patterns worth knowing cold

  • Slow/fast pointers — find the middle, detect cycles (Floyd's algorithm), find the k-th-from-end node.
  • Dummy/sentinel node — eliminates special-casing the head in insert/delete logic.
  • In-place reversal — three pointers (prev, curr, next), O(1) space.
  • Two-list merge — splice nodes from two sorted lists using a dummy head and a tail pointer.

Where this shows up in practice

Doubly linked lists paired with a hash map are the standard way to implement an O(1) LRU cache — the list tracks recency order, the hash map gives O(1) lookup to a node.

Practice Questions

Q1.What is a node in a singly linked list composed of?

Q2.What is the time complexity to access the k-th element of a singly linked list?

Q3.What is the time complexity to insert a new node at the head of a singly linked list, given a pointer to the head?

Q4.Compared to an array, what is the main advantage of a linked list for insertions/deletions in the middle?

Q5.What additional pointer does a node in a doubly linked list have compared to a singly linked list?

Q6.What is the classic technique to detect a cycle in a linked list in O(1) space?

Q7.In Floyd's cycle detection algorithm, how do the two pointers move?

Q8.How do you find the middle node of a singly linked list in one pass?

Q9.What's the time complexity of reversing a singly linked list iteratively?

Q10.What extra space does the standard iterative in-place linked list reversal use?

Q11.What is a common approach to merge two sorted linked lists into one sorted list?

Q12.To remove the n-th node from the end of a linked list in one pass, what technique is used?

Q13.What is a "sentinel" (or "dummy") node used for in linked list problems?

Q14.What defines a circular linked list?

Q15.What's the time complexity of searching for a value in an unsorted singly linked list?

Q16.Why is binary search NOT efficient on a singly linked list even if it's sorted?

Q17.What is a key real-world use case where a doubly linked list is preferred, combined with a hash map?

Q18.How do you typically check if a singly linked list is a palindrome in O(1) extra space?

Q19.What happens if you forget to update the previous node's next pointer when deleting a node from a singly linked list?

Q20.When finding the intersection point of two singly linked lists that merge into one, what's a common O(n) time, O(1) space technique?

Q21.What is the space complexity of a recursive linked list traversal in terms of call stack usage?

Q22.Which scenario favors an array (or dynamic array) over a linked list?

Q23.What's the main memory overhead of a linked list compared to an array of the same elements?

Q24.In a doubly linked list, what is the time complexity to delete a node given a direct pointer/reference to that node?

Q25.What does it mean for a linked list traversal to have poor cache locality compared to an array traversal?

Questions & Answers

Try answering in your head first, then click a question to check the model answer.

Q1.What is a linked list, and how does it differ fundamentally from an array in terms of memory layout?(show answer)

A linked list is a sequence of nodes where each node holds a value and a pointer to the next node; nodes can be scattered anywhere in memory. An array stores elements in one contiguous memory block. This is why arrays support O(1) index access (compute an offset) while linked lists require O(n) traversal from a known node to reach an arbitrary position.

Q2.When would you choose a linked list over a dynamic array?(show answer)

When you need frequent insertions or deletions at arbitrary positions (given a pointer to the location) without shifting other elements, or when the maximum size is unknown and you want to avoid the occasional O(n) resize/copy a dynamic array incurs when it grows. Trade this against losing O(1) random access and cache locality.

Q3.Walk through how you'd reverse a singly linked list iteratively.(show answer)

Keep three pointers: prev (starts null), curr (starts at head), and next. At each step, save curr.next into next, point curr.next to prev, then advance prev = curr and curr = next. Repeat until curr is null; prev is now the new head. This runs in O(n) time and O(1) extra space.

Q4.How would you detect whether a linked list contains a cycle, and why does the two-pointer approach work?(show answer)

Use Floyd's cycle detection: a slow pointer moves one node at a time, a fast pointer moves two. If there's no cycle, the fast pointer reaches null. If there is a cycle, the fast pointer eventually laps the slow pointer inside the loop and they meet — like two runners on a circular track at different speeds, the faster one must eventually catch the slower one.

Q5.Once you've detected a cycle with slow/fast pointers, how do you find where the cycle begins?(show answer)

After the pointers meet inside the cycle, reset one pointer to the head and keep the other at the meeting point. Move both one step at a time; the node where they meet again is the start of the cycle. This follows from the mathematical relationship between the distance to the cycle start and the cycle length established during the first phase.

Q6.Why can't you binary search a sorted linked list efficiently?(show answer)

Binary search relies on jumping directly to the middle element in O(1), which arrays support via index arithmetic. A linked list has no random access — reaching the "middle" requires traversing from the head, which is O(n) per lookup, erasing binary search's advantage entirely. Sorted linked lists are still searched linearly in practice.

Q7.Describe an approach to find the middle node of a linked list in a single pass.(show answer)

Use slow and fast pointers starting at the head. Advance slow by one node and fast by two nodes per iteration. When fast reaches the end (or null), slow is at the middle. This avoids a first pass to count length and a second pass to reach the middle.

Q8.How would you merge two already-sorted singly linked lists into one sorted list?(show answer)

Use a dummy head node and a tail pointer. Compare the current nodes of both lists, append the smaller one to the result, and advance that list's pointer. Repeat until one list is exhausted, then append the remainder of the other. This runs in O(n + m) time and O(1) extra space (excluding the output list itself).

Q9.What is the "dummy node" (or sentinel node) technique, and why is it useful?(show answer)

A dummy node is a placeholder created before the real head, so operations like insertion/deletion at the head don't need special-cased logic separate from the rest of the list. You build/modify the list starting from dummy.next, then return dummy.next as the real head at the end — it eliminates a whole class of null-pointer edge cases.

Q10.How do you remove the n-th node from the end of a linked list in one traversal?(show answer)

Use two pointers separated by a gap of n nodes: advance a "fast" pointer n steps ahead first, then move both fast and slow together until fast reaches the end. At that point, slow is just before the node to remove, so you can unlink it directly.

Q11.How would you check whether a linked list is a palindrome, ideally in O(1) extra space?(show answer)

Find the middle of the list (slow/fast pointers), reverse the second half in place, then compare the first half against the reversed second half node by node. If you need to restore the list afterward, reverse the second half back. This avoids the O(n) space of copying values into an array.

Q12.Two singly linked lists eventually merge into a shared tail. How do you find the intersection node efficiently?(show answer)

Traverse both lists; when a pointer reaches the end of its list, redirect it to the head of the other list. Both pointers together traverse a combined distance of lengthA + lengthB, so they arrive at the intersection node at the same time (or both hit null simultaneously if there's no intersection) — no extra space needed beyond the two pointers.

Q13.What's the difference in deletion complexity between a singly linked list and a doubly linked list, given a direct reference to the node to delete?(show answer)

In a singly linked list, deleting an arbitrary node given only a reference to it (not the head) is awkward — you typically need the previous node, which means an O(n) search unless you use a trick like copying the next node's value over and deleting the next node instead. In a doubly linked list, each node already has a prev pointer, so deletion given a direct reference is a true O(1) operation.

Q14.What is an LRU cache, and why is a doubly linked list combined with a hash map a natural fit for implementing one?(show answer)

An LRU (Least Recently Used) cache evicts the least recently accessed item when it's full. A doubly linked list maintains access order (most recently used at one end, least at the other) and supports O(1) removal/insertion at either end given a node reference; a hash map gives O(1) lookup from key to that node. Together they give O(1) get/put with correct eviction order — an array or singly linked list alone can't hit O(1) for both.

Q15.What's a common bug when deleting a node from a singly linked list, and how do you avoid it?(show answer)

Forgetting to update the previous node's next pointer — if you only null out the target node's own next, it stays reachable from the list and traversal doesn't actually skip it. Always keep track of the previous node while traversing, and set prev.next = curr.next to properly unlink the node.

Q16.Explain the space complexity difference between recursive and iterative traversal of a linked list.(show answer)

Recursive traversal uses O(n) space due to the call stack — each recursive call adds a stack frame until the base case. Iterative traversal with a loop and a pointer uses O(1) additional space. For very long lists, recursion risks a stack overflow that an iterative approach avoids.

Q17.What is a circular linked list, and what's one practical use case for it?(show answer)

A circular linked list is one where the last node's next pointer points back to an earlier node (commonly the head) instead of null, forming a loop. A practical use is round-robin scheduling — cycling through a fixed set of tasks or players — since you can traverse indefinitely and wrap around without special-casing "the end."

Q18.Why does a linked list typically have worse cache performance than an array, even for the same sequential traversal?(show answer)

Array elements are stored contiguously, so a CPU cache line loaded for one element often contains several subsequent elements too, minimizing cache misses. Linked list nodes are usually allocated at arbitrary times and scattered across memory (poor spatial locality), so each traversal step is more likely to be a cache miss even though both are conceptually O(n) traversals.

Q19.How would you split a linked list into two halves?(show answer)

Use slow/fast pointers to find the middle (the "find middle" pattern), then cut the link: set the node just before the second half's start to point to null, giving you two independent lists — the original head through the middle, and the middle's next through the end.

Q20.What's the trade-off of using a doubly linked list over a singly linked list?(show answer)

A doubly linked list allows O(1) backward traversal and O(1) deletion given a direct node reference, at the cost of extra memory per node (an additional pointer) and slightly more bookkeeping on every insert/delete. Choose it when you need to traverse backward or delete arbitrary nodes efficiently; otherwise a singly linked list is simpler and leaner.

Q21.How would you detect and remove duplicate values from an unsorted singly linked list?(show answer)

With extra space: traverse once, keeping a hash set of seen values; when you encounter a duplicate, unlink it. This is O(n) time, O(n) space. Without extra space: for each node, scan the rest of the list for duplicates and remove them — O(n²) time, O(1) space. The hash-set approach is preferred unless memory is very constrained.

Q22.How is inserting a new node into the middle of a linked list, given a pointer to the preceding node, different from inserting into an array at the same logical position?(show answer)

In a linked list, given a reference to the preceding node, insertion is O(1): create the new node, point it to prev.next, then point prev.next to the new node. In an array, inserting at the same logical position requires shifting every subsequent element over by one, which is O(n) regardless of whether you already know the index.

Q23.What is a "skip list," and how does it relate to linked lists?(show answer)

A skip list is a linked-list-based structure with multiple layers of forward pointers — higher layers skip over many nodes, letting you approximate binary-search-like O(log n) average search, insert, and delete on an ordered sequence, something a plain linked list can't do. It trades extra memory (for the multiple pointer layers) for much faster search than a single-layer linked list.

Q24.In an interview, why might reversing a linked list "in groups of k" be a meaningfully harder problem than a full reversal?(show answer)

A full reversal only needs three pointers and one pass. Reversing in groups of k requires reversing each k-sized segment independently while correctly re-linking each reversed segment to the next one (and handling a final group with fewer than k nodes), which means tracking segment boundaries and stitching multiple reversed sub-lists back together — more bookkeeping and more edge cases.

Q25.What's a subtle edge case interviewers often check for in any linked-list problem?(show answer)

The empty list (head is null) and the single-node list. Many linked-list algorithms implicitly assume at least two nodes (e.g., slow/fast pointer patterns, "previous node" tracking) and will null-pointer-dereference or behave incorrectly if you don't explicitly handle these boundary cases first.