1. 程式人生 > >leetcode_效率題解_[python/C++]_147. Insertion Sort List(連結串列插入排序)

leetcode_效率題解_[python/C++]_147. Insertion Sort List(連結串列插入排序)

題目連結
【題目】
Sort a linked list using insertion sort.

這裡寫圖片描述

【分析】
首先複習一下插入排序:

void insert_sort( int a[] , int n ){
    int i,j,temp;
    for( i = 1; i < n; i ++ ){
        temp = a[i];
        for( j = i-1 ; j >= 0 ; j -- ){
            if( temp < a[j] )
                a[j + 1] = a[j];
        }
        a[j+1
] = temp; } }

從0到size-1遍歷,對於每個位置,對其值與前面已經排序的各個位置進行比較找到應該插入的位置

對於連結串列的排序就煩人多了
但是思想還是一樣的,關鍵是對於指標的概念要清晰

先來看下面我一開始寫的解法:
flag==>遍歷所在位置
pre_flag==>flag的前一個結點
temp==>flag前面從前往後遍歷的結點
pre==>temp的前一個結點
boo==>布林值來判斷temp到達flag之前是否已經找到合適的插入位置

class Solution {
public:
    ListNode*
insertionSortList(ListNode* head) { if( !head || !head->next ) return head; ListNode * new_list = new ListNode(0); new_list->next = head; ListNode * pre_flag = head; ListNode * flag = head->next; bool boo = false; while(flag != NULL){ ListNode *
temp = new_list->next; ListNode * pre = new_list; boo = false; while( temp != flag ){ if( temp->val <= flag->val ){ temp = temp->next; pre = pre->next; } else{ ListNode * temp_node = new ListNode(flag->val); flag = flag->next; pre_flag->next = flag; temp_node->next = temp; pre->next = temp_node; boo = true; break; } } if(!boo){ pre_flag = flag; flag = flag->next; } } return new_list->next; } };

可是跑出來的效率是這樣的
這裡寫圖片描述

再看看上面的解法為什麼這麼慢,原因是因為有時候遍歷到的flag值已經比前一個大,那就沒有必要再找插入位置了,直接繼續往後flag=flag->next就好了
優化程式碼:

class Solution {
public:
    ListNode* insertionSortList(ListNode* head) {
        if( !head || !head->next ) return head;
        ListNode * new_list = new ListNode(0);
        new_list->next = head;
        ListNode * pre_flag = head;
        ListNode * flag = head->next;
        while(flag != NULL){
            if(pre_flag->val > flag->val){
                ListNode * temp = new_list->next;
                ListNode * pre = new_list;
                boo = false;
                while( temp != flag ){
                    if( temp->val <= flag->val ){
                        temp = temp->next;
                        pre = pre->next;
                    }
                    else{
                        ListNode * temp_node = new ListNode(flag->val);
                        flag = flag->next;
                        pre_flag->next = flag; 
                        temp_node->next = temp;
                        pre->next = temp_node;
                        break;
                    }
                }
            }

            else{
                pre_flag = flag;
                flag = flag->next;
            }

        }
        return new_list->next;

    }
};

這個效率就是最前面給出的runtime,90%

當然可以寫成下面一種簡潔點的寫法:

class Solution {
public:
    ListNode* insertionSortList(ListNode* head) {
        ListNode * new_list = new ListNode(0);
        new_list->next = head;
        ListNode * flag = head;
        ListNode * pre = new_list;
        while(flag){
            if( flag->next && flag->next->val < flag->val ){
                while( pre->next && pre->next->val < flag->next->val ) pre = pre->next;
                /* Insert flag -> next after pre.*/
                ListNode * temp = pre->next;
                pre->next = flag->next;
                flag->next = flag->next->next;
                pre->next->next = temp;
                /* Move pre back to new_list. */
                pre = new_list;
            }
            else{
                flag = flag->next;
            }
        }
        ListNode * ans = new_list->next;
        delete new_list;
        return ans;
    }
};

效率是一樣的

再看看python的程式碼:

# Definition for singly-linked list.
# class ListNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution(object):
    def insertionSortList(self, head):
        p = new_list = ListNode(0)
        flag = new_list.next = head
        while flag and flag.next:
            val = flag.next.val
            if flag.val < val:
                flag = flag.next
                continue
            if p.next.val > val:
                p = new_list
            while p.next.val < val:
                p = p.next
            temp = flag.next
            flag.next = temp.next
            temp.next = p.next
            p.next = temp
        return new_list.next

這裡寫圖片描述