欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

[LC] 328. Odd Even Linked List

程序员文章站 2022-07-14 08:45:41
...

[LC] 328. Odd Even Linked List

https://leetcode.com/problems/odd-even-linked-list/

很久没有试过不看提示自己很快解决一道medium题了,今天终于搞定了一道。也不知道是不是因为太简单了。。
这题一个很直接的一个想法就是将链表先分拆成两条链,一条odds链一条even链然后odds链连接even链就可以了。关键就是如何分拆了。我看到这题目的时候让我有点想到当年我遇到的第一条LinkedList相关的算法题,reverse a linkedlist,这一题in place的做法是利用前中后三个指针不停往下循环。然后我试着画了一下,如果这一题也是三个指针,前中后,会如何。结果发现....就做出来了。首先是三个指针,prev, curr, next,prev最开始是head,curr最开始是head.next(并且这个curr其实就是分拆的两条链的第二条链的头),next就是curr.next(如果有的话)。然后就不停这么一个循环:prev.next = next; prev = curr; curr = next; next = next.next; 直到curr == null。此时两条链就形成了,然后再从head找到第一条链的最后一个点,和第二条链的头连起来,就行了。说起来有点抽象,自己画一画操作一下就明白了。就此,给出代码如下:

    public ListNode oddEvenList(ListNode head) {
        if (head == null) return null;

        ListNode secondHead = head.next;
        ListNode prev = head, current = head.next, next = current == null ? null : current.next;
        while (current != null) {
            prev.next = next;
            prev = current;
            current = next;
            next = next == null ? null : next.next;
        }
        
        ListNode tail = head;
        while (tail.next != null) {
            tail = tail.next;
        }
        
        tail.next = secondHead;
        return head;
    }

基本上,第一个while loop这就是一个很安全的,把当前的节点的next连接到当前的节点的next的next并且还能遍历完整条链表的一个做法。在这个连接的过程里,两条链表就自动分拆完成了。当然,我见到提交的答案里有一个很屌的只遍历一遍并且只用两个临时节点就完成的做法,给出代码参考一下就好了。我觉得我要面试的话我就会给刚才自己想到的代码就好了:

    public ListNode oddEvenList(ListNode head) {
        if (head == null) {
            return null;
        }
        ListNode odd = head, even = head.next, evenHead = even;
        while (even != null && even.next != null) {
            odd.next = even.next;
            odd = odd.next;
            even.next = odd.next;
            even = even.next;
        }
        odd.next = evenHead;
        return head;
    }

这个做法的思路其实就很明晰了,一开始就分清楚了odd链和even链的头,odd链不停往下连自己该连接的节点,even链不停往下连自己该连接的节点。odd指向的必然就是odd链的结尾,直接连even链的头就可以了。比我的更聪明些。