LeetCode 使用原地算法实现单链表的特殊旋转

问题描述:

将给定的单链表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}.
Given a singly linked list L: L 0→L 1→…→L n-1→L n,

reorder it to: L 0→L n →L 1→L n-1→L 2→L n-2→…

You must do this in-place without altering the nodes' values.

For example,
Given{1,2,3,4}, reorder it to{1,4,2,3}.

 

解题思路:考虑把原始链表拆分为两个,利用快慢指针可以找到链表的中间节点

    再把后面部分的链表实现翻转,使用原地算法

    再把两个链表合并为一个链表即实现上述要求

/**
 * 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) {
        if(head == null || head.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 mid = slow.next;
        slow.next = null;
        ListNode after = getReverse(mid);
        getAdd(head, after);
    }
    public ListNode getReverse(ListNode node){
        ListNode pre = null;
        while(node != null){
            ListNode temp = node.next;
            node.next = pre;
            pre = node;
            node = temp;
        }
        return pre;
    }
    public void getAdd(ListNode node1,ListNode node2){
        while(node1 != null && node2 !=null){
            ListNode f = node1.next;
            ListNode a = node2.next;
            node1.next = node2;
            node1 = f;
            node2.next = node1;        
            node2 = a;
        }
    }
}
posted @ 2019-12-11 21:16  老干妈不太辣  阅读(33)  评论(0编辑  收藏  举报