|
| 1 | +--- |
| 2 | +title: Reverse Linked List |
| 3 | +commit: 6aa5e19 |
| 4 | +url: https://github.com/josimar-silva/kaizen/commit/6aa5e19e1b6f63cb07e6114c8b68deac21d2f548 |
| 5 | +--- |
| 6 | + |
| 7 | +### Reversing a Linked List |
| 8 | + |
| 9 | +### 1. The Iterative Approach (In-Place) |
| 10 | + |
| 11 | +This method walks through the list and reverses the direction of the `next` pointers at each node. It's highly efficient as it doesn't use extra memory proportional to the list's size. |
| 12 | + |
| 13 | +#### Analogy: The Train Uncoupling |
| 14 | + |
| 15 | +Imagine a train on a track. To reverse it, you can't just turn the whole train around. Instead, a worker walks from the engine to the caboose, uncoupling each car and re-coupling it to the one behind it. |
| 16 | + |
| 17 | +- `currentNode`: The car the worker is currently at. |
| 18 | +- `previousNode`: The car that has just been re-coupled, now part of the "reversed" section. |
| 19 | +- `nextNode`: The worker keeps an eye on the next car in the original sequence, so they know where to go next after re-coupling the current one. |
| 20 | + |
| 21 | +This process continues until the last car is reached, which then becomes the new engine. |
| 22 | + |
| 23 | +#### Big O Analysis |
| 24 | + |
| 25 | +- **Time Complexity: O(n)** |
| 26 | + We visit each node in the list exactly once to rewire its `next` pointer. If the list has `n` nodes, we perform `n` operations. |
| 27 | + |
| 28 | +- **Space Complexity: O(1)** |
| 29 | + The memory required is constant. We only need three pointers (`previousNode`, `currentNode`, `nextNode`) to keep track of our state, regardless of whether the list has 10 nodes or 10 million. |
| 30 | + |
| 31 | +--- |
| 32 | + |
| 33 | +### 2. The Recursive Approach |
| 34 | + |
| 35 | +This method uses the function call stack to reverse the list. It traverses to the end of the list and then, as the stack unwinds, it reverses the pointers. |
| 36 | + |
| 37 | +#### Analogy: The Domino Chain Reaction |
| 38 | + |
| 39 | +Think of the list as a line of dominoes. |
| 40 | + |
| 41 | +1. **The Walk:** You walk to the very last domino in the line without touching any of them. This is the recursive traversal. |
| 42 | +2. **The Base Case:** You arrive at the last domino. This is the new "head" of the reversed line. |
| 43 | +3. **The Chain Reaction:** You tip the last domino so it falls backward, hitting the one before it (`head.next.next = head`). As each recursive call returns, it does the same, causing a chain reaction backward until the original first domino is the new last one. |
| 44 | + |
| 45 | +#### Big O Analysis |
| 46 | + |
| 47 | +- **Time Complexity: O(n)** |
| 48 | + Similar to the iterative approach, each node is visited once during the traversal to the end. |
| 49 | + |
| 50 | +- **Space Complexity: O(n)** |
| 51 | + This is the key difference. For each node we traverse, a new frame is added to the function call stack. For a list of `n` nodes, the stack depth will be `n`. This means memory usage grows linearly with the size of the list. |
| 52 | + |
| 53 | +--- |
| 54 | + |
| 55 | +### Conclusion & Key Takeaways |
| 56 | + |
| 57 | +| Approach | Time | Space | Analogy | When to Use | |
| 58 | +| :--------- | :----- | :----- | :--------------------- | :----------------------------------------------------------------------- | |
| 59 | +| **Iterative** | O(n) | O(1) | Train Uncoupling | Preferred in most production scenarios, especially with large inputs. | |
| 60 | +| **Recursive** | O(n) | O(n) | Domino Chain Reaction | Good for conceptual understanding, but risky for large inputs due to potential **stack overflow** errors. | |
| 61 | + |
| 62 | +**Lesson Learned:** The choice between iteration and recursion often comes down to a trade-off between implementation simplicity and space efficiency. |
0 commit comments