This ended up a bit extreme. I suggest to read the original one at the bottom first, which also includes an explanation. Then move upwards through the updates.

## Update 4:

"Code golf" (6 lines)

Not fully golfed, but yeah...

```
ListNode* reverseBetween(ListNode *head, int m, int n) {
ListNode **a = &head, **b;
for (;m--; n--)
a = &(*(b=a))->next;
for (;n--; swap(*b, *a))
swap(*b, (*a)->next);
return head;
}
```

## Update 3:

Pointer pointers (8 lines)

Removed duplicate code.

```
ListNode* reverseBetween(ListNode *head, int m, int n) {
ListNode **pivot = &head, **prev;
for (int i=0; i<m; i++)
pivot = &(*(prev=pivot))->next;
for (int i=m; i<n; i++) {
swap(*prev, (*pivot)->next);
swap(*prev, *pivot);
}
return head;
}
```

## Update 2:

Pointer pointers (9 lines)

Using a second pointer pointer.

```
ListNode* reverseBetween(ListNode *head, int m, int n) {
ListNode **prev = &head;
for (int i=1; i<m; i++)
prev = &(*prev)->next;
ListNode **pivot = &(*prev)->next;
for (int i=m; i<n; i++) {
swap(*prev, (*pivot)->next);
swap(*prev, *pivot);
}
return head;
}
```

## Update 1:

Pointer pointer (9 lines)

Motivated by quick glance at lchen77's solution.

```
ListNode* reverseBetween(ListNode *head, int m, int n) {
ListNode **prev = &head;
for (int i=1; i<m; i++)
prev = &(*prev)->next;
ListNode *pivot = *prev;
for (int i=m; i<n; i++) {
swap(*prev, pivot->next->next);
swap(*prev, pivot->next);
}
return head;
}
```

## Dummy node (10 lines)

My original one.

```
ListNode* reverseBetween(ListNode *head, int m, int n) {
ListNode dummy(0), *prev = &dummy;
dummy.next = head;
for (int i=1; i<m; i++)
prev = prev->next;
ListNode *pivot = prev->next;
for (int i=m; i<n; i++) {
swap(prev->next, pivot->next->next);
swap(prev->next, pivot->next);
}
return dummy.next;
}
```

Some explanation: First I find the node right *before* the first node in the reverse range. I call it `prev`

. And I call the first node *in* the reverse range `pivot`

. Then this pivot node goes through the reverse range. Every next node it encounters is moved behind `prev`

, i.e., to the start of the reverse range.

So before the reversing, I'm in this situation:

```
prev pivot
| |
[A] --> [B] --> [C] --> [D] --> [E] --> [F] --> ...
```

In front of the pivot we have node C, which gets moved to after prev, and pivot moves on:

```
prev pivot
| |
[A] --> [C] --> [B] --> [D] --> [E] --> [F] --> ...
```

So far the range from B to C has been reversed. If that was the goal, we can stop now. Otherwise... Now in front of the pivot we have node D, which gets moved to after prev, and pivot moves on:

```
prev pivot
| |
[A] --> [D] --> [C] --> [B] --> [E] --> [F] --> ...
```

So far the range from B to D has been reversed. If that was the goal, we can stop now. Otherwise... Now in front of the pivot we have node E, which gets moved to after prev, and pivot moves on:

```
prev pivot
| |
[A] --> [E] --> [D] --> [C] --> [B] --> [F] --> ...
```

So far the range from B to E has been reversed. If that was the goal, we can stop now. Otherwise...

And so on...

Note that taking out a node in front of the pivot and inserting it after prev involves modifying three pointers: `prev->next`

, `pivot->next`

and `pivot->next->next`

. I do it with two swaps, but it could also be done with a helper variable and four assignments:

```
for (int i=m; i<n; i++) {
auto next = pivot->next;
pivot->next = next->next;
next->next = prev->next;
prev->next = next;
}
```