题目描述:
给定一个单链表的头部节点head,链表长度为N,如果N为偶数,那么前N/2个节点算zuobanqu左半区,后N/2算右半区;如果N为奇数,那么前N/2个节点算左半区,后N/2 + 1个节点算作右半区。左半区从左到右依次记为L1->L2->…,右半区从左到右依次记为R1->R2->…,请将单链表调整成L1->R1->L2->R2->…的形式
例如:
1—>NULL 调整后:1—>NULL
1—>2—>NULL 调整后:1—>2—>NULL
1—>2—>3—>NULL 调整后:1—>2—>3—>NULL
1—>2—>3—>4—>NULL调整后:1—>3—>2—>4—>NULL
1—>2—>3—>4—>5—>NULL调整后:1—>3—>2—>4—>5—>NULL
1—>2—>3—>4—>5—>6—>NULL调整后:1—>4—>2—>5—>3—>6—>NULL
要求:假设链表长度为N,时间复杂度为O(N),额外空间复杂度为O(1)
思路:利用快慢指针将左半区和右半区进行分离,分离为两个独立的链表,然后将右半区链表的各个节点插入左半区的链表中
public class Code_021_ReconfigureList {
public static class Node {
public int data;
public Node next;
public Node(int data) {
this.data = data;
}
}
public static void reconfigureList(Node head) {
if (head == null || head.next == null) {
return;
}
Node mid = head; //slow
Node right = head.next; //quick
while(right.next != null && right.next.next != null) {
mid = mid.next;
right = right.next.next;
}
right = mid.next;
mid.next = null;
mergeLR(head, right);
}
public static void mergeLR(Node left, Node right) {
Node next = null;
while(left.next != null) {
next = right.next;
right.next = left.next;
left.next = right;
left = right.next;
right = next;
}
left.next = right;
}
}