题目

类型:Stack

难度:中等

重排链表 - 图1

解题思路

目标链表即为将原链表的左半端和反转后的右半端合并后的结果。

即可划分为三步:

1、找到原链表的中点

我们可以使用快慢指针来找到链表的中间节点

2、将原链表的右半端反转

我们可以使用迭代法实现链表的反转。

3、将原链表的两端合并。

因为两链表长度相差不超过 11,因此直接合并即可。

代码

  1. class Solution {
  2. public void reorderList(ListNode head) {
  3. if (head == null) {
  4. return;
  5. }
  6. ListNode mid = middleNode(head);
  7. ListNode l1 = head;
  8. ListNode l2 = mid.next;
  9. mid.next = null;
  10. l2 = reverseList(l2);
  11. mergeList(l1, l2);
  12. }
  13. public ListNode middleNode(ListNode head) {
  14. ListNode slow = head;
  15. ListNode fast = head;
  16. while (fast.next != null && fast.next.next != null) {
  17. slow = slow.next;
  18. fast = fast.next.next;
  19. }
  20. return slow;
  21. }
  22. public ListNode reverseList(ListNode head) {
  23. ListNode prev = null;
  24. ListNode curr = head;
  25. while (curr != null) {
  26. ListNode nextTemp = curr.next;
  27. curr.next = prev;
  28. prev = curr;
  29. curr = nextTemp;
  30. }
  31. return prev;
  32. }
  33. public void mergeList(ListNode l1, ListNode l2) {
  34. ListNode l1_tmp;
  35. ListNode l2_tmp;
  36. while (l1 != null && l2 != null) {
  37. l1_tmp = l1.next;
  38. l2_tmp = l2.next;
  39. l1.next = l2;
  40. l1 = l1_tmp;
  41. l2.next = l1;
  42. l2 = l2_tmp;
  43. }
  44. }
  45. }