鏈表算法

本文主要總結鏈表算法中常用技術點

有序鏈表

1、合併有序鏈表

將兩個有序鏈表合併爲一個新的有序鏈表並返回,新鏈表是通過拼接給定的兩個鏈表的所有節點組成的。 

https://leetcode-cn.com/problems/merge-two-sorted-lists/

該算法主要就步驟是:

(1)確定鏈表頭結點

       第一種方法可以判斷哪個鏈表頭大或者小,選擇其中一個座位頭結點;第二種方法是創建一個新節點,他的next指向頭結點

(2)選擇結點放在新鏈表中(升序爲例)

        兩個指針分別指向兩個鏈表,一次比較兩個指針結點的值,將小的節點放在新鏈表後面,並將指向這個節點的指針後移

(3)將沒有遍歷完成的隊列放在新鏈表後面

2、鏈表排序

    鏈表排序使用的是歸併排序,該算法主要步驟如下:

      (1)找到中間位置

               使用快慢指針的方法找到中間節點,注意快節點的初始值爲head->next,如果爲fast=head的時候 當只有兩個節點會出現無限循環( sortList)

     (2)中間節點左右兩部分進行有序鏈表合併操作

              return mergerList(sortList(head), sortList(fast));,該算法由於遞歸會最終遞歸到2個節點排序,4個節點排序,依次類推完全符合歸併排序的思路見(https://leetcode-cn.com/problems/sort-list/

反轉鏈表

1、 反轉鏈表

      反轉鏈表有兩種方法 

(1)指針法

思路是不斷在老的鏈表中摘取節點,放在新鏈表的前面。

 head指針指向新鏈表頭結點、q指針指向老鏈表的頭結點,r指向老鏈表頭結點的下一個節點

(2)棧結構

由於棧是先進後出,所以剛好滿足反轉,不過該方法的空間和時間複雜度高一些

2、 鏈表相加

鏈表相加就是數字相加,數據現加是從低位向高位進位,所以需要先把鏈表倒置,然後從前向後依次相加,注意進位;最終相加完再將鏈表倒置即可(https://leetcode-cn.com/problems/reverse-linked-list-ii/  https://leetcode-cn.com/problems/reverse-linked-list/

3、 鏈表迴文

(1)後半部分倒轉

先使用快慢指針找到中間位置,找到以後將後半部分進行倒轉,倒轉以後跟前半部分一一對比即可

(2)前半部分倒轉

使用快慢指針找到中間部分,找的過程中用棧存儲慢指針數據,注意快指針最後是否爲空,不爲空說明爲奇數個節點,中間指針在向前移動一步,後半部分跟棧中數據進行比較即可

https://leetcode-cn.com/problems/palindrome-linked-list/

刪除鏈表

由於刪除數據可能會刪除頭結點數據,當刪除頭結點數據的時候不是很好操作,所以一般刪除操作都會引入輔助結點,創建一個新節點,該節點的next爲head,最後再刪除該節點即可

1、 刪除重複數據

鏈表中有重複的元素,刪除所有重複元素或者刪除重複元素使其不重複(https://leetcode-cn.com/problems/remove-duplicates-from-sorted-list-ii/  https://leetcode-cn.com/problems/remove-duplicates-from-sorted-list/

2、刪除倒數第n個節點

兩個指針一個指向輔助節點,一個指向頭結點,然後先將指向頭結點向後移動n個節點

之後兩個指針同時向前移動,當指向頭結點的指針指向尾部NULL時,指向輔助節點的next剛好爲倒數第n個節點

3、 移除元素

沒有給定鏈表,僅僅是給定了鏈表中執行刪除的元素,並將該元素刪除,

void deleteNode(ListNode* node) {
        ListNode* tmp=node->next;
        node->val=tmp->val;
        node->next=tmp->next;
        delete(tmp);
        
    }

相交鏈表

1、判斷鏈表是否有環,有環的話找到相交點

 快慢指針相遇點到入環點的距離 = 頭結點到入環點的距離”:將頭結點到入環點的這一段環繞在環上,那麼快慢指針相遇點即爲出發點,即快慢指針相遇點到入環點的距離,等於頭結點到入環點的距離。 步驟一:判斷是否有環:快慢指針 步驟二:找出入環點:雙指針

ListNode *detectCycle(ListNode *head) {
        if(head==NULL or head->next==NULL) return NULL;
        ListNode* fast=head;
        ListNode* slow=head;
        while(fast!=NULL && fast->next!=NULL){
            fast=fast->next->next;
            slow=slow->next;
            if(fast==slow ) {
                slow=head;
                while(slow!=fast){
                    slow=slow->next;
                    fast=fast->next;
                }
                return slow;
            }
        }
          
        return NULL;
    }

https://leetcode-cn.com/problems/linked-list-cycle-ii/

2、兩個鏈表相交,求相交點

這個是沒有環的相交,求該相交點的方式是:先得到兩個鏈表的長度,然後求出差值diff,長鏈表指針先走diff步,然後兩個鏈表指針一起走,兩個指針第一次相同的位置就是相交處

https://leetcode-cn.com/problems/intersection-of-two-linked-lists/

 

鏈表類型主要是這麼多,後續發現新題型在繼續添加

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章