linecode 99. 重排链表java 实现AC

/*
 99. 重排链表
给定一个单链表L: L0→L1→…→Ln-1→Ln,

重新排列后为:L0→Ln→L1→Ln-1→L2→Ln-2→…

必须在不改变节点值的情况下进行原地操作。
样例

给出链表 1->2->3->4->null,重新排列后为1->4->2->3->null
 */

方案1:

 class Node1{
    int value;
    Node1 next;
    public Node1(int value){
        this.value=value;
        this.next=null;
    }
}

public class Solution {
    public void reOderList(Node1 head){
        /*
        1.一个指针指向头结点,一个指针只向尾节点
        2.定义一个临时节点
         */
        if(head==null||head.next==null||head.next.next==null) return ;

            Node1 p=head, pEnd=head.next,temp=new Node1(0);
            Node1 Head=temp;
            while(p!=pEnd){
                //1.每次指向第一个节点
                temp.next=p;
                p=p.next;
                temp=temp.next;

                //2.先找到最后一个节点)
                while(pEnd.next!=null){
                    //pEnd只向最后一个节点
                    pEnd=pEnd.next;
                }
                //然后指向最后一个节点(
                temp.next=pEnd;
                temp=temp.next;
                pEnd=p.next;

            }
            head=Head.next;

    }
}
/*
OUT:
Time Limit Exceeded
总耗时: 1581 ms
37% 数据通过测试.
输入

2->-1->0->null

期望答案

2->0->-1->null

提示
你的代码运行时间超过了限制,
检查你的时间复杂度。
TLE通常是由死循环造成的,
思考一下你的时间复杂度是否是最优的。
 */

方案2:
class ListNode{
    int value;
    ListNode next;
    public ListNode(int value ){
        this.value=value;
        this.next=null;
    }
}
/*
1.先找中点,将链表一分为二(快慢法)
2.再将后面的部分翻转(因为涉及到链表前一节点问题)
3.再将两个链表合并,注意交叉合并
 */
public class Solution99 {
    //1.先找中点,将链表一分为二(快慢法)
    private ListNode findMiddle(ListNode head) {
        ListNode slow = head, fast = head.next;
        while (fast != null && fast.next != null) {
            fast = fast.next.next;
            slow = slow.next;
        }
        return slow;
    }
   // 2.再将后面的部分翻转(因为涉及到链表前一节点问题)
    private ListNode reverse(ListNode head) {
        ListNode newHead = null;
        while (head != null) {
            ListNode temp = head.next;
            head.next = newHead;
            newHead = head;
            head = temp;
        }
        return newHead;
    }
    //3.再将两个链表合并,注意交叉合并
    private void merge(ListNode head1, ListNode head2) {
        int index = 0;
        ListNode newln = new ListNode(0);
        while (head1 != null && head2 != null) {
            if (index % 2 == 0) {
                newln.next = head1;
                head1 = head1.next;
            } else {
                newln.next = head2;
                head2 = head2.next;
            }
            newln = newln.next;
            index ++;
        }
        if (head1 != null) {
            newln.next = head1;
        } else {
            newln.next = head2;
        }
    }


    public void reorderList(ListNode head) {
        if (head == null || head.next == null) {
            return;
        }

        ListNode mid = findMiddle(head);
        ListNode tail = reverse(mid.next);
        mid.next = null;

        merge(head, tail);
    }
}
AC
阅读更多

没有更多推荐了,返回首页