力扣(LeetCode) -143 重排链表

本题考察的是快慢指针和一些链表插入删除等操作

题目描述

给定一个单链表 L:L0→L1→…→Ln-1→Ln ,
将其重新排列后变为: L0→Ln→L1→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.

题目思考

我们首先使用快慢指针找到链表中间的结点,然后把中间结点和他的后驱(.next)断开,形成两个前半截和后半截链表。我们把后半截链表反转,然后把后半截链表的结点依次插入到前半截链表中即可。如下图所示。

image.png

代码

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public void reorderList(ListNode head) {
        if(head==null||head.next==null)
            return ;
        ListNode res=head;
        ListNode fast=head;
        ListNode slow=head;
        while(fast.next!=null&&fast.next.next!=null){  //使用快慢指针找到中间结点
            fast=fast.next.next;
            slow=slow.next;
        }
        ListNode pre=null,cur=slow.next;   //截成两个链表
        slow.next=null;
        while(cur!=null){    //反转第二个链表
            ListNode temp=cur.next;
            cur.next=pre;
            pre=cur;
            cur=temp;
        }
        while(pre!=null){   //将第二个链表的结点依次插入第一个链表
            ListNode temp1=res.next;
            ListNode temp2=pre.next;
            res.next=pre;
            pre.next=temp1;
            res=temp1;
            pre=temp2;
        }
    }
}

你可能感兴趣的:(力扣(LeetCode) -143 重排链表)