每日一题.147. 对链表进行插入排序

对链表进行插入排序。
插入排序的动画演示如上。从第一个元素开始,该链表可以被认为已经部分排序(用黑色表示)。
每次迭代时,从输入数据中移除一个元素(用红色表示),并原地将其插入到已排好序的链表中。

我的解法:在原始链表上维护一个已排序链表sort,sort的头节点p和尾节点q在初始时都指向head,h为未排序待处理的节点,每次取sort之后的第一个节点为h。为了减少算法的搜索次数,首先判断h所指节点的值是否小于sort的头节点p,若小于,则直接将h插入到链表头部;然后判断h所指节点的值是否大于sort的尾节点q,若大于,则直接将q和h后移一位;最后,若h的大小介于p和q之间,则遍历sort,找到h合适的插入位置并插入。

时间复杂度:O(n2),空间复杂度:O(1)

class Solution {
    public ListNode insertionSortList(ListNode head) {
        if (head == null || head.next == null) {
            return head;
        }
        ListNode p = head, q = head, h = head.next;
        while (h != null) {
            p = head;
            /*h所指节点小于已排序链表的头节点*/
            if (p.val >= h.val) {
                q.next = h.next;
                h.next = p;
                p = h;
                head = p;
                h = q.next;
            } else if (q.val <= h.val) {
                /*h所指节点大于已排序链表的尾节点*/
                q = h;
                h = h.next;
            } else {
                /*h所指节点的大小介于头节点和尾节点之间*/
                while (p.val != q.val) {
                    /*找到合适的位置,将h所指的节点插入*/
                    if (p.next.val > h.val) {
                        break;
                    }
                    p = p.next;
                }
                q.next = h.next;
                h.next = p.next;
                p.next = h;
                h = q.next;
            }
        }
        return head;
    }
}

你可能感兴趣的:(每日一题.147. 对链表进行插入排序)