牛客题目链接
1. 题目考点
- 找链表中间节点的两种方式
- 翻转链表的两种方式
2. 考点解析
- 原地构造两个链表 list1 和 list2,list2 采用头插法翻转原链表
public ListNode reorderList(ListNode head) {
ListNode l1 = new ListNode(0);
ListNode l2 = new ListNode(0);
ListNode r1 = l1, r2 = l2, p = head;
r1.next = head;
int len = getLen(head);
int mid = len >> 1;
while (mid != 0) {
mid --;
r1 = p;
p = p.next;
}
r1.next = null;
while (p != null) {
ListNode temp = p.next;
p.next = l2.next;
l2.next = p;
p = temp;
}
ListNode dummy = new ListNode(0);
ListNode r = dummy;
r1 = l1.next;
r2 = l2.next;
while (r1 != null && r2 != null) {
r.next = r1;
r1 = r1.next;
r = r.next;
r.next = r2;
r2 = r2.next;
r = r.next;
}
if (r1 != null) r.next = r1;
if (r2 != null) r.next = r2;
return dummy.next;
}
public int getLen(ListNode node) {
int i = 0;
while (node != null) {
i++;
node = node.next;
}
return i;
}
- 采用快慢指针划分链表为 list1 和 list2,list2 原地翻转,
原地插入合并 list1 和 list2
public void reorderList(ListNode head) {
if(head == null || head.next == null)
return ;
ListNode fast = head;
ListNode slow = head;
while(fast != null && fast.next != null){
slow = slow.next;
fast = fast.next.next;
}
ListNode mid = slow;
ListNode p = mid.next;
mid.next = null;
ListNode pre = null;
while(p != null){
ListNode temp = p.next;
p.next = pre;
pre = p;
p = temp;
}
ListNode p1 = head, p2 = pre;
while(p1 != null && p2!=null){
ListNode next1 = p1.next;
ListNode next2 = p2.next;
p1.next = p2;
p2.next = next1;
p1 = next1;
p2 = next2;
}
return ;
}