当前位置:   article > 正文

给定一个单链表 L 的头节点 head ,单链表 L 表示为:L0 → L1 → … → Ln - 1 → Ln请将其重新排列后变为:L0 → Ln → L1 → Ln - 1_给定一个单链表 l:l0→l1→…→ln-1→ln , 将其重新排列后变为: l0→ln→l1→ln

给定一个单链表 l:l0→l1→…→ln-1→ln , 将其重新排列后变为: l0→ln→l1→ln-1

力扣原题:

 先贴代码:

  1. public class Solution143 {
  2. public void reorderList(ListNode head) {
  3. //找到原链表的中间节点
  4. ListNode mid = middleNode(head);
  5. //将原链表中点之后的链表反转逆置,再返回反转后的头节点
  6. ListNode last = Reverse(mid);
  7. //使中点的next域为空,断开链表
  8. mid.next = null;
  9. //将链表的前半部分和反转后的后半部分合并
  10. merge(head,last);
  11. }
  12. public ListNode middleNode(ListNode head){
  13. //寻找链表中点的方法为快慢指针法
  14. ListNode slow = head;
  15. ListNode fast = head;
  16. //快指针每次走两步,慢指针每次走一步,等快指针到终点的时候慢指针正好在链表的中间位置
  17. while (fast != null && fast.next != null){
  18. fast = fast.next.next;
  19. slow = slow.next;
  20. }
  21. //返回慢指针所在的节点,即为中间节点
  22. return slow;
  23. }
  24. public ListNode Reverse(ListNode mid){
  25. //将中点之后的链表进行反转,使后一个节点指向前一个节点
  26. ListNode cur = mid.next;
  27. ListNode tmp = mid; //为了避免混淆,新建一个tmp节点替代mid进入循环
  28. while (cur != null){
  29. ListNode ret = cur.next;
  30. cur.next = tmp;
  31. tmp = cur;
  32. cur = ret;
  33. }
  34. return tmp;
  35. }
  36. public void merge(ListNode l1 ,ListNode l2){
  37. //最后进行合并操作,若原链表为奇数情况则l1和l2相遇时循环结束;
  38. // 偶数情况则是l2的next域为null时循环结束
  39. while (l1 != l2 && l2.next != null){
  40. ListNode cur = l1.next;
  41. ListNode tmp = l2.next;
  42. l1.next = l2;
  43. l2.next = cur;
  44. l2 = tmp;
  45. l1 = cur;
  46. }
  47. }
  48. }

思路解析: 

题目中要求我们将链表按照一定顺序重新排列,如下图演示,意思就是将倒数第一个排在第一个后面,倒数第二个排在第二个后面,依此类推。

 由上图我们可以看到,原来链表的中间节点经重新排列后变成了最后一个节点,通过这点我们便可以从中间节点入手来解决问题。

因为单链表只能指向它的后继节点无法指向前驱节点,所以直接将最后一个节点排在第一个后面后,我们无法再对倒数第二个节点进行操作;必须先将原链表分为两个部分,把后半部分的链表再进行反转逆置操作,这样原来链表的最后一个节点就变成了后半部分链表的头节点,最后把前半部分链表和后半部分链表再来一个合并操作(按题目里的排列顺序合并),就可以解决问题了!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/226646
推荐阅读
相关标签
  

闽ICP备14008679号