原题链接

讨论澄清

这里首先要解决的一个问题就是如何找到链表的中点,关于如何找中点,这里可以利用快慢指针找中点.接下来是以中点将链表分成两部分,并将后一部分链表进行反转,之后再将反转后的链表一次插入前一个链表中,这个题目细想起来就是三个知识点融合起来:找链表中点、反转链表、将一个链表按要求插入另外一个链表,这三部分的操作都是经典的必须掌握的基础链表知识。

思路简述

首先对边界条件也就是空链表的情况加以判断,之后通过快慢指针找到链表的中点,并且将一个链表分成两个链表,之后将后一个链表反转,在之后将后一个链表的每一个元素插到前一个链表的中间,如果有多出来的未插入的情况则放在前一个链表的最末尾。

注意事项

注意这里的边界条件是链表为空的情况,要单独加以判断。

具体代码

  1. /**
  2. * Definition for singly-linked list.
  3. * public class ListNode {
  4. * int val;
  5. * ListNode next;
  6. * ListNode() {}
  7. * ListNode(int val) { this.val = val; }
  8. * ListNode(int val, ListNode next) { this.val = val; this.next = next; }
  9. * }
  10. */
  11. class Solution {
  12. public void reorderList(ListNode head) {
  13. //判断边界条件
  14. if(head==null){
  15. return;
  16. }
  17. //首先找出中点
  18. ListNode mid = finMid(head);
  19. //将中点之后的链表反转,先拿到中点之后的点
  20. ListNode l2 = mid.next;
  21. mid.next = null;
  22. l2 = reverse(l2);
  23. //将反转后的链表一次插入到前半段链表中
  24. ListNode l1 = head;
  25. while(l1!=null&&l2!=null){
  26. ListNode next = l1.next;
  27. l1.next = l2;
  28. l2 = l2.next;
  29. l1.next.next = next;
  30. l1 = next;
  31. }
  32. }
  33. //使用快慢指针的方式来实现中点节点的查询
  34. public ListNode finMid(ListNode head){
  35. //经典查询方法
  36. ListNode fast = head;
  37. ListNode slow = head;
  38. while(fast!=null&&fast.next!=null){
  39. fast= fast.next.next;
  40. slow = slow.next;
  41. }
  42. return slow;
  43. }
  44. //反转链表
  45. public ListNode reverse(ListNode head){
  46. ListNode newnode = null;
  47. ListNode next = head;
  48. while(head!=null){
  49. //经典四步判断
  50. next = head.next;
  51. head.next = newnode;
  52. newnode = head;
  53. head = next;
  54. }
  55. return newnode;
  56. }
  57. }