链表交替排列

本文介绍如何使用原地算法重排单链表,通过快慢指针找到中点,将链表分为两部分,然后反转后半部分并逐步连接。适合0到200000长度链表,值域0到1000。
* 将给定的单链表\ L L: L_0→L_1→…→L_{n-1}→L_ nL
 * 0
 * <p>
 * →L
 * 1
 * <p>
 * →…→L
 * n−1
 * <p>
 * →L
 * n
 *
 * <p>
 * 重新排序为:L_0→L_n →L_1→L_{n-1}→L_2→L_{n-2}→…L
 * 要求使用原地算法,不能只改变节点内部的值,需要对实际的节点进行交换。
 * <p>
 * 数据范围:链表长度 0 \le n \le 200000≤n≤20000 ,链表中每个节点的值满足 0 \le val \le 10000≤val≤1000
 * <p>
 */
public class A068_reorderList {
    public static void reorderList(ListNode head) {
        if (head == null || head.next == null || head.next.next == null) {
            return;
        }
        //找中点,链表分成两个
        ListNode slow = head;
        ListNode fast = head;
        //快慢指针,把整个链表分开成两部分
        while (fast.next != null && fast.next.next != null) {
            slow = slow.next;
            fast = fast.next.next;
        }
        ListNode newHead = slow.next;
        //要断开后面的
        slow.next = null;
        //第二个链表倒置,反转后半部分链表
        newHead = reverseList(newHead);
        //链表节点依次连接
        while (newHead != null) {
            //先把后半部分逆序的链表下个节点保存为临时节点
            ListNode temp = newHead.next;
            //把下个节点的next指向头结点的下一个节点
            newHead.next = head.next;
            //头结点的下一个指向新的节点
            head.next = newHead;
            //头节点重新赋值(此时的newHead.next已经是指向)
            head = newHead.next;
            //把临时保存的节点赋值给新的节点
            newHead = temp;
        }
    }

    /**
     * 链表进行反转
     *
     * @param head
     * @return
     */
    private static ListNode reverseList(ListNode head) {
        if (head == null) {
            return null;
        }
        ListNode curr = head;
        ListNode prev = null;
        while (curr != null) {
            ListNode temp = curr.next;
            curr.next = prev;
            prev = curr;
            curr = temp;
        }
        return prev;
    }

}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值