reorder-list反转链表

题目描述:

将给定的单链表L: L 0→L 1→…→L n-1→L n,

重新排序为: L 0→L n →L 1→L n-1→L 2→L n-2→…

要求使用原地算法,并且不改变节点的值

例如:

对于给定的单链表{1,2,3,4},将其重新排序为{1,4,2,3}.

解题思路:

1、把链表分成两部分,如1->2->3->4->5->null,分成l1 : 1->2->3->null,和l2 : 4->5->null

2、将第二个链表反转, 所以l2  :  5->4->null

3、将2个链表合并

/**
 * Definition for singly-linked list.
 * class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public void reorderList(ListNode head) {
        //当链表为空,或只有1个2个Node时,不需要反转
        if (head == null || head.next == null || head.next.next == null)
            return;
        ListNode slow = head;
        ListNode fast = head;
        //最终slow指向的位置是reorder之后的最后一个Node
        while(fast != null && fast.next != null){
            slow = slow.next;
            fast = fast.next.next;
        }
        //slow不可能是Null,end2也不会是Null
        //end2指向l2的end node
        ListNode end2 = slow.next;
        //ppre指向要反转的node的前一个node
        ListNode ppre = end2;
        //p指向要反转的node
        ListNode p = ppre.next;
        //pnext指向要反转的node的下一个node,也就是下一个要反转的node
        ListNode pnext = null;
        //p指向null时,反转结束
        while(p != null){
            pnext = p.next;
            p.next = ppre;
            ppre = p;
            p = pnext;
        }
        //反转结束,ppre指向l2的start node
        ListNode start2 = ppre;
        //将两个链表分离,使各自的end node指向null
        end2.next = null;
        slow.next = null;
        //得到了2个链表l1和l2
        ListNode l1 = head;
        ListNode l2 = start2;
        //为连接l1和l2所用,在改变node.next前要记录之前的node.next
        ListNode l1next = null;
        ListNode l2next = null;
        //合并链表
        while(l1 != null && l2 != null){
            l1next = l1.next;
            l2next = l2.next;
            l1.next = l2;
            l1 = l1next;
            l2.next = l1;
            l2 = l2next;
        }
    }
}
发布了52 篇原创文章 · 获赞 6 · 访问量 8990

猜你喜欢

转载自blog.csdn.net/PMPWDF/article/details/104030416