赞
踩
力扣原题:
先贴代码:
- public class Solution143 {
- public void reorderList(ListNode head) {
- //找到原链表的中间节点
- ListNode mid = middleNode(head);
- //将原链表中点之后的链表反转逆置,再返回反转后的头节点
- ListNode last = Reverse(mid);
- //使中点的next域为空,断开链表
- mid.next = null;
- //将链表的前半部分和反转后的后半部分合并
- merge(head,last);
- }
- public ListNode middleNode(ListNode head){
- //寻找链表中点的方法为快慢指针法
- ListNode slow = head;
- ListNode fast = head;
- //快指针每次走两步,慢指针每次走一步,等快指针到终点的时候慢指针正好在链表的中间位置
- while (fast != null && fast.next != null){
- fast = fast.next.next;
- slow = slow.next;
- }
- //返回慢指针所在的节点,即为中间节点
- return slow;
- }
- public ListNode Reverse(ListNode mid){
- //将中点之后的链表进行反转,使后一个节点指向前一个节点
- ListNode cur = mid.next;
- ListNode tmp = mid; //为了避免混淆,新建一个tmp节点替代mid进入循环
- while (cur != null){
- ListNode ret = cur.next;
- cur.next = tmp;
- tmp = cur;
- cur = ret;
- }
- return tmp;
- }
- public void merge(ListNode l1 ,ListNode l2){
- //最后进行合并操作,若原链表为奇数情况则l1和l2相遇时循环结束;
- // 偶数情况则是l2的next域为null时循环结束
- while (l1 != l2 && l2.next != null){
- ListNode cur = l1.next;
- ListNode tmp = l2.next;
- l1.next = l2;
- l2.next = cur;
- l2 = tmp;
- l1 = cur;
- }
- }
- }

思路解析:
题目中要求我们将链表按照一定顺序重新排列,如下图演示,意思就是将倒数第一个排在第一个后面,倒数第二个排在第二个后面,依此类推。
由上图我们可以看到,原来链表的中间节点经重新排列后变成了最后一个节点,通过这点我们便可以从中间节点入手来解决问题。
因为单链表只能指向它的后继节点无法指向前驱节点,所以直接将最后一个节点排在第一个后面后,我们无法再对倒数第二个节点进行操作;必须先将原链表分为两个部分,把后半部分的链表再进行反转逆置操作,这样原来链表的最后一个节点就变成了后半部分链表的头节点,最后把前半部分链表和后半部分链表再来一个合并操作(按题目里的排列顺序合并),就可以解决问题了!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。