# [LeetCode] 6-chain list reordering

Keywords: Programming

### subject

Given a single-chain list L:L 0_L 1..._L-n-1_L-n,

Reordering is: L 0_L n_L 1_L n-1_L 2_L n-2...

Local algorithm is required without changing the value of the node

For example:

For a given single-chain list {1,2,3,4}, reorder it to {1,4,2,3}.

### Solution-Storage

The disadvantage of chain lists is that they cannot be stored randomly. When we want to retrieve the end element, we can only iterate through it from the beginning, which is time consuming.The second time you take the end element, you have to go through it again.

So let's start with a simple, crude idea of storing a list of chains in a linear table, then using a double pointer to pull the elements from the beginning to the end.

``````public void reorderList(ListNode head) {
return;
}
//Save in list
List<ListNode> list = new ArrayList<>();
}
//Head and tail pointers take elements in turn
int i = 0, j = list.size() - 1;
while (i < j) {
list.get(i).next = list.get(j);
i++;
//Even number of nodes will meet ahead of time
if (i == j) {
break;
}
list.get(j).next = list.get(i);
j--;
}
list.get(i).next = null;
}
``````

### Solution 2 recursion

As mentioned in Solution 1, our problem is that when we take the tail element, we need to traverse the list once.

It would be easier if our recursive function could return the tail element corresponding to the current header element and complete the list of chains between the header and tail elements as required. As shown above, we only need to point the header to tail and tail to the processed chain header. img

And then we'll put the previousTail.nextBack is the tail for the outer head er.

If there is only one node, then we only need toHead.nextReturn.

``````if (len == 1) {
return outTail;
}
``````

If it's two nodes, we need toHead.next.nextReturn.

``````if (len == 2) {
return outTail;
}
``````

Then the overall code is what it looks like below

``````public void reorderList(ListNode head) {

return;
}
int len = 0;
//Find out the number of nodes
while (h != null) {
len++;
h = h.next;
}

}

private ListNode reorderListHelper(ListNode head, int len) {
if (len == 1) {
return outTail;
}
if (len == 2) {
return outTail;
}
//Gets the corresponding end node and recursively processes the list of chains between the head and end nodes
ListNode tail = reorderListHelper(head.next, len - 2);
ListNode outTail = tail.next;  //tail corresponding to the previous head er
return outTail;
}
``````

### Solution 3

It mainly takes advantage of the characteristics of the elements from end to end.

There are three main steps, for example.

```1 -> 2 -> 3 -> 4 -> 5 -> 6
The first step is to divide the list equally into two halves
1 -> 2 -> 3
4 -> 5 -> 6

Step 2, reverse the second list
1 -> 2 -> 3
6 -> 5 -> 4

Step 3, Join two linked lists in turn
1 -> 6 -> 2 -> 5 -> 3 -> 4
```

If the first step is to find the midpoint, you can apply the fast or slow pointer.The fast pointer takes two steps at a time and the slow pointer takes one step at a time. When the fast pointer reaches the end, the slow pointer will just reach the midpoint.If the number of nodes is even, slow goes to the left endpoint, which allows us to combine odd and even cases without having to consider them separately.

In the second step, there are two ways of iteration and recursion if the chain list is in reverse order. In the case of iteration, two pointers are used to reverse the order.

The third step is very simple. Move the two pointers back separately.

``````public void reorderList(ListNode head) {
return;
}
//Find the midpoint and divide the list into two
while (fast.next != null && fast.next.next != null) {
slow = slow.next;
fast = fast.next.next;
}

slow.next = null;

//Second Chain List Inverted

}

}

return null;
}

tail.next = null;