重排链表(Java实现)

题目描述:

给定一个单链表 LL0→L1→…→Ln-1→Ln ,
将其重新排列后变为: L0→LnL1→Ln-1→L2→Ln-2→…

你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。

示例 1:

给定链表 1->2->3->4, 重新排列为 1->4->2->3.

示例 2:

给定链表 1->2->3->4->5, 重新排列为 1->5->2->4->3.

解题思路:

  1. 先找到原链表的中间节点,然后切断中间节点与上一个节点的练习。
  2. 反转原链表中间节点为头节点的链表。
  3. 按照给定的重排方式将原链表与反转后的链表拼接起来。

代码实现:

class Solution {
    public void reorderList(ListNode head) {
        if (head == null || head.next == null) {
            return;
        }
        ListNode t = head;
        //先找到中间节点
        ListNode temp = findMidNode(head);
        ListNode midNode = temp.next;
        temp.next = null;
        //反转中间节点为头节点的链表
        midNode = reverseNode(midNode);
        //按照特定顺序将原链表的前一半与反转后的链表拼接起来
        ListNode newNode = new ListNode(-1);
        ListNode n = newNode;
        int flag = 1;
        while (t != null && midNode != null) {
            if(flag % 2 == 1) {
                n.next = t;
                t = t.next;
            }else {
                n.next = midNode;
                midNode = midNode.next;
            }
            flag++;
            n = n.next;
        }
        if (t == null && midNode != null) {
            n.next = midNode;
        }else if (t != null && midNode == null) {
            n.next = t;
        } 
        head = newNode.next;
    }
    //找到链表的中间节点的上一个节点
    private ListNode findMidNode(ListNode head) {
        ListNode f = head;
        ListNode s = head;
        while(f.next != null && f.next.next != null) {
            s = s.next;
            f = f.next.next;
        }
        return s;
    }
    //反转节点
    private ListNode reverseNode(ListNode head) {
        ListNode dummyHead = new ListNode(-1);
        dummyHead.next = head;
        ListNode f = head;
        ListNode s = f.next;
        while (s != null) {
            f.next = s.next;
            s.next = dummyHead.next;
            dummyHead.next = s;
            s = f.next;
        }
        return dummyHead.next;
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_43573824/article/details/88648560