单向链表-奇偶链表

今天学习的算法是奇偶链表,自己实现后发现虽然方法大致思路是对的。但是最后提交完看解题答案发现竟然还可以这么简单。

题目介绍

奇偶链表就是给定一个单向链表,将从头部开始遍历,次序为奇数的节点排在前面,序号为偶数的节点排在后面。我们用张图来表示下吧:


奇偶链表题目.png

实现思路

老规矩,先看解题思路图。


奇偶链表-解题.png
难点说明

1.定义三个变量,奇数尾节点,偶数头节点以及偶数尾节点。其中偶数头节点固定赋值为头节点的next节点。
2.每次遍历时先将奇数尾节点指向next的next节点,再将偶数尾节点指向next的next节点。原因是偶数节点一定在奇数节点后,为了防止指针丢失。
3.从第2步可以看出,循环结束的条件就是要求奇数尾节点的next和偶数尾节点的next都不为空。

重点关注下边界情况,仔细分析

  • 链表的长度为奇数,那么最后奇数尾节点和偶数尾节点的next都为null,此时只要再进行一步将奇数尾节点的next指向偶数头节点即可。
  • 链表的长度为偶数,那么最后奇数尾节点和偶数尾节点的next都指向最后一个节点,而最后一个节点为偶数节点,因此仍然只需将奇数尾节点的next指向偶数头节点即可。

综上分析,算法实现时循环结束后最后一步都只需将奇数尾节点指向偶数头节点。而无需做特殊处理。

实现代码

优化前
public ListNode oddEvenList(ListNode head){
    if(null == head || null == head.next){
        return head;
    }

    ListNode oddTailNode = head;

    ListNode evenHeadNode = head.next;
    ListNode evenTailNode = head.next;

    ListNode P = head.next.next;
    int index = 1;
    while (null != P){
        if((index % 2)==1){
            oddTailNode.next = P;
            oddTailNode = P;
        }else{
            evenTailNode.next = P;
            evenTailNode = P;
        }
        P = P.next;
        index++;
    }
    evenTailNode.next = null;
    oddTailNode.next = evenHeadNode;
    return head;
}
优化后
public ListNode oddEvenList(ListNode head) {
    if (null == head || null == head.next) {
        return head;
    }

    ListNode oddTail = head;
    ListNode evenHead = head.next, evenTail = head.next;

    while (null != oddTail.next && null != evenTail.next) {
        oddTail.next = oddTail.next.next;
        oddTail = oddTail.next;
        evenTail.next = evenTail.next.next;
        evenTail = evenTail.next;

    }
    oddTail.next = evenHead;
    return head;
}

你可能感兴趣的:(单向链表-奇偶链表)