DEV Community

Abhishek Gupta
Abhishek Gupta

Posted on

Linked List Mistakes Every Beginner Makes (Including Me)

Today, I spent almost 3–4 hours solving a Medium-level Linked List problem on LeetCode: Swap Nodes in Pairs.

At first, I thought the problem was simple.

The task was basically:

1 → 2 → 3 → 4
Enter fullscreen mode Exit fullscreen mode

Convert it into:

2 → 1 → 4 → 3
Enter fullscreen mode Exit fullscreen mode

I thought:

"Okay, I just need to swap every two nodes. How difficult can that be?"

But once I started writing the code, things became confusing.

I wrote the solution.

Got an error.

Dry-ran the code.

Found another mistake.

Changed the logic.

Created more variables.

Forgot to update a pointer.

And suddenly, my entire logic became messy. 😅

After spending hours on this one problem, I learned something important about Linked Lists.

Linked Lists are not difficult because of syntax. They are difficult because you need to understand references and pointers.

In this article, I want to share the mistakes I made and the mistakes I think almost every beginner makes while learning Linked Lists.


First, What Actually Is a Linked List?

Let's take a simple Linked List:

1 → 2 → 3 → 4 → null
Enter fullscreen mode Exit fullscreen mode

Each node contains two things:

  1. A value
  2. A reference to the next node

We can visualize a node like this:

┌─────────┬──────────┐
│  Value  │   Next   │
└─────────┴──────────┘
Enter fullscreen mode Exit fullscreen mode

For example:

┌───────┬───────┐
│   1   │   ●───┼──→ Node 2
└───────┴───────┘
Enter fullscreen mode Exit fullscreen mode

The last node points to:

null
Enter fullscreen mode Exit fullscreen mode

The head usually points to the first node.

head
 ↓
1 → 2 → 3 → 4 → null
Enter fullscreen mode Exit fullscreen mode

Everything starts from head.


Mistake 1: Thinking a Variable Creates a New Node

This is one of the first mistakes beginners make.

Suppose we write:

let first = head;
Enter fullscreen mode Exit fullscreen mode

Some beginners may think that first now contains a copy of the first node.

But that's not true.

first is simply another reference to the same node.

head ─────┐
          ↓
        [1] → [2] → [3]
          ↑
          │
first ────┘
Enter fullscreen mode Exit fullscreen mode

Both head and first point to the same node.

So if you create another variable like:

let current = head;
Enter fullscreen mode Exit fullscreen mode

You now have:

head ──────┐
current ───┼──→ [1] → [2] → [3]
           │
           └── Same Node
Enter fullscreen mode Exit fullscreen mode

You did not create another Linked List.

You just created another reference.

Important Lesson

A variable in a Linked List usually stores a reference to a node, not a copy of the node.

Understanding this makes many Linked List problems easier.


Mistake 2: Not Understanding the Difference Between Moving a Pointer and Changing a Link

This is extremely important.

Suppose:

1 → 2 → 3 → 4
Enter fullscreen mode Exit fullscreen mode

And:

let current = head;
Enter fullscreen mode Exit fullscreen mode

Currently:

current
   ↓
1 → 2 → 3 → 4
Enter fullscreen mode Exit fullscreen mode

Now if we write:

current = current.next;
Enter fullscreen mode Exit fullscreen mode

What happens?

current moves to the next node.

1 → 2 → 3 → 4
    ↑
 current
Enter fullscreen mode Exit fullscreen mode

Notice something important.

The Linked List itself did not change.

Only the variable moved.


But now look at this:

current.next = current.next.next;
Enter fullscreen mode Exit fullscreen mode

This changes the actual connection between nodes.

Before:

1 → 2 → 3 → 4
↑
current
Enter fullscreen mode Exit fullscreen mode

After changing current.next:

1 ─────→ 3 → 4
Enter fullscreen mode Exit fullscreen mode

Node 2 has been disconnected.

So remember:

Moving a variable

current = current.next;
Enter fullscreen mode Exit fullscreen mode

Means:

Move my reference.

Changing .next

current.next = something;
Enter fullscreen mode Exit fullscreen mode

Means:

Change the Linked List structure.

This difference is very important.


Mistake 3: Accessing .next Without Checking for null

Suppose your Linked List is empty:

head = null
Enter fullscreen mode Exit fullscreen mode

And you write:

let second = head.next;
Enter fullscreen mode Exit fullscreen mode

This will cause an error because head does not exist.

Similarly:

1 → null
Enter fullscreen mode Exit fullscreen mode

If you do:

head.next.next
Enter fullscreen mode Exit fullscreen mode

You may get an error.

Because:

head.next = null
Enter fullscreen mode Exit fullscreen mode

And null.next does not exist.

This is why conditions are important.

For example:

while (current && current.next) {
    // Safe to work with two nodes
}
Enter fullscreen mode Exit fullscreen mode

Before accessing a node's .next, ask:

Does this node actually exist?


Mistake 4: Forgetting to Save the Next Node

This is one of the biggest mistakes when modifying a Linked List.

Suppose:

1 → 2 → 3 → 4
Enter fullscreen mode Exit fullscreen mode

You are currently at node 1.

current
   ↓
1 → 2 → 3 → 4
Enter fullscreen mode Exit fullscreen mode

Now imagine you change:

current.next = something;
Enter fullscreen mode Exit fullscreen mode

The original connection might be lost.

For example, if you overwrite:

1 → 2
Enter fullscreen mode Exit fullscreen mode

You may lose your connection to node 2.

That is why, before changing a connection, it is often useful to save the next node.

Conceptually:

let nextNode = current.next;
Enter fullscreen mode Exit fullscreen mode

Now:

current → 1 → 2 → 3 → 4
              ↑
           nextNode
Enter fullscreen mode Exit fullscreen mode

Even if you change current.next, you still know where node 2 is.

Simple Rule

Before breaking a connection, make sure you have saved the node you need later.

This single habit can prevent many Linked List bugs.


Mistake 5: Forgetting to Update Pointers

This was personally my biggest mistake.

While solving Swap Nodes in Pairs, I created pointers like:

prev
current
next
Enter fullscreen mode Exit fullscreen mode

For example:

prev → 1 → 2 → 3 → 4
       ↑   ↑
   current next
Enter fullscreen mode Exit fullscreen mode

Then I swapped 1 and 2.

After swapping:

prev → 2 → 1 → 3 → 4
Enter fullscreen mode Exit fullscreen mode

The swap is complete.

But now comes the important question:

Where should my pointers go next?

Many beginners, including me, focus completely on the swap but forget to move the pointers for the next iteration.

After swapping:

prev → 2 → 1 → 3 → 4
Enter fullscreen mode Exit fullscreen mode

The next pair is:

3 → 4
Enter fullscreen mode Exit fullscreen mode

So our pointers need to move accordingly.

If you forget to update them, you might:

  • Process the same nodes again
  • Skip nodes
  • Get stuck in an infinite loop
  • Access the wrong node

This taught me:

Creating a pointer is easy. Updating it correctly is the difficult part.

After every operation, ask yourself:

Where is prev now?
Where is current now?
Where is next now?
Which node should I process next?
Enter fullscreen mode Exit fullscreen mode

Mistake 6: Updating Pointers in the Wrong Order

In Linked Lists, the order of operations matters.

Let's say we have:

prev → first → second → remaining
Enter fullscreen mode Exit fullscreen mode

And we want:

prev → second → first → remaining
Enter fullscreen mode Exit fullscreen mode

There are multiple connections we need to change.

If we randomly change pointers without thinking, we can lose part of the list.

Instead, visualize every step.

Before swapping

prev → first → second → remaining
Enter fullscreen mode Exit fullscreen mode

Connect first to remaining

first.next = second.next
Enter fullscreen mode Exit fullscreen mode

Now first knows where the remaining list starts.

Connect second to first

second.next = first
Enter fullscreen mode Exit fullscreen mode

Now:

second → first → remaining
Enter fullscreen mode Exit fullscreen mode

Connect prev to second

prev.next = second
Enter fullscreen mode Exit fullscreen mode

Final structure:

prev → second → first → remaining
Enter fullscreen mode Exit fullscreen mode

The lesson here is:

Don't just write pointer operations. Understand what every line does to the structure.


Mistake 7: Not Using a Dummy Node

The first node of a Linked List is special because head points to it.

Suppose:

head
 ↓
1 → 2 → 3 → 4
Enter fullscreen mode Exit fullscreen mode

After swapping the first pair:

2 → 1 → 3 → 4
Enter fullscreen mode Exit fullscreen mode

Now the head needs to point to 2.

This creates an extra case.

But we can simplify this using a dummy node.

dummy → 1 → 2 → 3 → 4
Enter fullscreen mode Exit fullscreen mode

Now we can treat the first pair just like every other pair.

Before:

dummy → first → second
Enter fullscreen mode Exit fullscreen mode

After:

dummy → second → first
Enter fullscreen mode Exit fullscreen mode

At the end:

return dummy.next;
Enter fullscreen mode Exit fullscreen mode

The dummy node is not part of the final answer.

It is just a helper.

When should beginners consider a Dummy Node?

Whenever:

  • The head might change
  • You need a previous pointer before the first node
  • You are deleting nodes
  • You are inserting nodes
  • You are swapping nodes

A dummy node can make the logic much cleaner.


Mistake 8: Creating Too Many Variables

This is something I personally did.

When I got confused, instead of simplifying the logic, I created more variables.

Something like:

let first = ...
let second = ...
let next = ...
let temp = ...
let current = ...
let previous = ...
let third = ...
Enter fullscreen mode Exit fullscreen mode

Then after some time, I forgot what each variable was supposed to do. 😅

The logic became messy in my head.

Instead, every pointer should have a clear responsibility.

For example:

prev    → Node before the pair
first   → First node of the pair
second  → Second node of the pair
Enter fullscreen mode Exit fullscreen mode

That's it.

When creating a variable, ask:

Why do I need this pointer?

If you cannot answer that clearly, you probably don't need it.


Mistake 9: Losing Part of the Linked List

This is a very common problem.

Suppose:

1 → 2 → 3 → 4 → 5
Enter fullscreen mode Exit fullscreen mode

You are working with:

1 → 2
Enter fullscreen mode Exit fullscreen mode

But you also need to remember:

3 → 4 → 5
Enter fullscreen mode Exit fullscreen mode

still exists.

If you incorrectly modify pointers, you might accidentally get:

2 → 1 → null
Enter fullscreen mode Exit fullscreen mode

And the remaining nodes:

3 → 4 → 5
Enter fullscreen mode Exit fullscreen mode

become disconnected.

The final answer will be wrong because you lost part of the list.

Whenever modifying nodes, think about the Linked List in three parts:

Previous | Current Nodes | Remaining Nodes
Enter fullscreen mode Exit fullscreen mode

For example:

dummy → 1 → 2 | 3 → 4 → 5
Enter fullscreen mode Exit fullscreen mode

Your job is to modify the current nodes while keeping the remaining list connected.

Always ask:

After changing this pointer, can I still reach the remaining nodes?


Mistake 10: Not Dry Running the Code

This was probably the thing that finally helped me solve the problem.

Initially, I was doing this:

Think → Write Code → Run
Enter fullscreen mode Exit fullscreen mode

Error.

Then again:

Think → Write Code → Run
Enter fullscreen mode Exit fullscreen mode

Another error.

Eventually, I stopped writing code.

I took a simple example:

1 → 2 → 3 → 4
Enter fullscreen mode Exit fullscreen mode

And drew every pointer.

dummy → 1 → 2 → 3 → 4
          ↑   ↑
        first second
Enter fullscreen mode Exit fullscreen mode

Then I executed one line at a time.

After every line, I asked:

What does the Linked List look like now?

This is extremely useful.

For Linked List problems:

Dry running is often more important than immediately writing code.

Take a pen and paper.

Draw boxes.

Draw arrows.

Move pointers.

You will understand the problem much faster.


Mistake 11: Forgetting How the Loop Moves Forward

In arrays, movement is easy.

for (let i = 0; i < n; i++) {
}
Enter fullscreen mode Exit fullscreen mode

The index automatically moves.

But in a Linked List, you need to manually move your pointers.

For example:

while (current) {
    current = current.next;
}
Enter fullscreen mode Exit fullscreen mode

The important line is:

current = current.next;
Enter fullscreen mode Exit fullscreen mode

Without it, current stays in the same place.

That can cause an infinite loop.

Always ask:

Which pointer is responsible for moving through the Linked List?

And after every iteration:

Did that pointer actually move forward?


Mistake 12: Forgetting Edge Cases

Before submitting a Linked List solution, test small inputs.

Empty List

[]
Enter fullscreen mode Exit fullscreen mode

One Node

1
Enter fullscreen mode Exit fullscreen mode

Two Nodes

1 → 2
Enter fullscreen mode Exit fullscreen mode

Odd Number of Nodes

1 → 2 → 3
Enter fullscreen mode Exit fullscreen mode

Even Number of Nodes

1 → 2 → 3 → 4
Enter fullscreen mode Exit fullscreen mode

Small test cases reveal most pointer mistakes.

For example, in Swap Nodes in Pairs:

1 → 2 → 3
Enter fullscreen mode Exit fullscreen mode

The answer should be:

2 → 1 → 3
Enter fullscreen mode Exit fullscreen mode

The last node should remain unchanged.

If your code assumes there are always two nodes available, it may fail.


Mistake 13: Accidentally Creating an Infinite Loop

Sometimes, while reconnecting nodes, beginners accidentally create a cycle.

For example:

1 → 2 → 3
    ↑     ↓
    └─────┘
Enter fullscreen mode Exit fullscreen mode

Now if you traverse the list:

while (current) {
    current = current.next;
}
Enter fullscreen mode Exit fullscreen mode

It will never reach null.

The program may run forever.

This usually happens when pointers are connected incorrectly.

After modifying a Linked List, always check:

  • Did I connect the correct nodes?
  • Did I accidentally point backward?
  • Can the traversal eventually reach null?

Mistake 14: Trying to Solve Everything in One Go

Sometimes beginners look at:

1 → 2 → 3 → 4 → 5 → 6
Enter fullscreen mode Exit fullscreen mode

And try to understand the entire transformation at once:

2 → 1 → 4 → 3 → 6 → 5
Enter fullscreen mode Exit fullscreen mode

This can be overwhelming.

Instead, break the problem into one small operation.

Focus only on:

1 → 2
Enter fullscreen mode Exit fullscreen mode

Swap it:

2 → 1
Enter fullscreen mode Exit fullscreen mode

Then move to:

3 → 4
Enter fullscreen mode Exit fullscreen mode

Swap it:

4 → 3
Enter fullscreen mode Exit fullscreen mode

Then:

5 → 6
Enter fullscreen mode Exit fullscreen mode

Swap it:

6 → 5
Enter fullscreen mode Exit fullscreen mode

Linked List problems become easier when you focus on a small local structure.


The Biggest Lesson I Learned

After spending almost 3–4 hours on one problem, I realized something.

My biggest problem wasn't the syntax.

It wasn't JavaScript.

It wasn't even the algorithm.

My biggest problem was:

I didn't know exactly where my pointers were pointing after every operation.

I would write some code.

Change connections.

Move some variables.

Then suddenly I would forget:

Where is current now?
Where is next now?
What happened to the previous node?
Which node should I process next?
Enter fullscreen mode Exit fullscreen mode

Once I started dry-running every step, things became clearer.


My New Mental Model for Linked Lists

Now whenever I solve a Linked List problem, I divide it into three parts:

Processed | Current | Remaining
Enter fullscreen mode Exit fullscreen mode

For example:

1 → 2 | 3 → 4 | 5 → 6
Enter fullscreen mode Exit fullscreen mode

Suppose I am currently working on:

3 → 4
Enter fullscreen mode Exit fullscreen mode

Then:

Processed       Current        Remaining

1 → 2      |    3 → 4    |    5 → 6
Enter fullscreen mode Exit fullscreen mode

My job is simple:

  1. Don't break the processed part.
  2. Modify the current nodes.
  3. Don't lose the remaining nodes.
  4. Move pointers to the next position.

This way of thinking has helped me a lot.


A Simple Checklist for Linked List Problems

Before writing code, I now ask myself:

1. What does each pointer represent?

prev = ?
current = ?
next = ?
Enter fullscreen mode Exit fullscreen mode

2. Can the head change?

If yes, maybe use a dummy node.

3. Can the list be empty?

head = null
Enter fullscreen mode Exit fullscreen mode

4. Can there be only one node?

1 → null
Enter fullscreen mode Exit fullscreen mode

5. Will changing .next disconnect part of the list?

Save important references first.

6. How will my pointers move forward?

Every loop iteration should make progress.

7. What is my stopping condition?

Don't access null.next.

8. Did I dry run small examples?

Always test:

[]
[1]
[1, 2]
[1, 2, 3]
[1, 2, 3, 4]
Enter fullscreen mode Exit fullscreen mode

Final Thoughts

Today, one Medium LeetCode problem took me almost 3–4 hours.

I got stuck multiple times.

I wrote the code again and again.

I made pointer mistakes.

I forgot to update references.

I made the logic complicated.

But I kept dry-running the problem until I finally understood it.

And honestly, I think spending those hours was worth it.

Because I didn't just solve one problem.

I learned how important it is to understand:

What is pointing where?

If you are a beginner learning Linked Lists, don't feel bad if they take time.

Linked Lists require visualization.

Take your time.

Draw the nodes.

Draw the arrows.

Write down your pointers.

Execute one line at a time.

And always remember:

Before changing a pointer, understand what connection you are breaking. After changing it, understand where your pointers should move next.

That's the lesson I learned today. 🚀


Related Links

🔗 LeetCode Problem: Swap Nodes in Pairs

📝 Solution 1: [https://leetcode.com/problems/swap-nodes-in-pairs/solutions/8493093/linked-list-pair-swapping-clean-optimal-ugwmp]

📝 Solution 2: [https://leetcode.com/problems/swap-nodes-in-pairs/solutions/8493072/swap-adjacent-nodes-using-pointer-manipu-fewq]


javascript #leetcode #dsa #datastructures #algorithms #linkedlist #programming #codingjourney #learninginpublic #beginners #100daysofcode

Top comments (0)