從尾到頭打印鏈表 之 “C++代碼+思路解析 ”(允許原地修改鏈表)

從尾到頭打印鏈表 之 “C++代碼+思路解析 ”(允許原地修改鏈表)

上一篇 從尾到頭打印鏈表 (第一種情況 不允許原地打印鏈表)

希望我的文字始終給您帶來畫面感。

其實做算法題的過程也是在考驗我們的大腦日常解決問題的能力,懂不懂得將生活中碰到的難題拆分,一一解決

今日感悟

//不要去刻意記憶代碼句,先用起來,積累框架,慢慢拿出來用。
//不是所有的框架都是一樣的,也要學會適應不同的變化。

題目開始咯!

  題目描述:輸入一個鏈表,按鏈表值從尾到頭的順序返回一個ArrayList。

//這裏敲黑板,千萬注意:我們做算法題 ,最基本的也是最關鍵的題目一定要 理解準確。這道題涉及到允不允許原地修改鏈表,所以分爲以下兩種情況。這裏是第二種情況。

 第二種情況:允許原地修改鏈表,那麼只需要用三個指針來解決。

代碼實現部分:

//5月9日
class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        ListNode* pre = nullptr;
        ListNode* cur = head;
        ListNode* next = nullptr;
        while(cur)
        {
            next = cur->next;
            
            cur->next = pre;
            
            pre = cur;
            cur = next;
        }
        
        return pre;
    }
};

思路解析部分:

我不知道大家的寫算法思路是思維習慣和先後順序是怎樣的,我會習慣將代碼拆分成小的代碼塊進行 ,再進行邏輯組合安裝。當然這裏無法評判哪種一定是正確的,這裏我想分享一下:我個人認爲最快的寫代碼順序。

第一步:我會先搞清楚題目 ,需要我給它一個什麼,定下來整體的框架。

這道題的第二種情況是允許原地修改鏈表,那麼只需要返回傳進來的鏈表就OK了,只不過這個鏈表被操作了一番。

那第一步函數整體的框架就出來咯!

class Solution {
public:
    ListNode* reverseList(  ) {
      
    .............................................
        
     return 頭指針;//鏈表被原地操作,此時的頭指針已經不是head了
    }
};

這裏的第二步:我會把參數定下來,進到函數體首先就檢查參數合不合法。

加入 if 語句檢驗參數 鏈表指針 head 是否爲空。


class Solution {
public:
    ListNode* reverseList( ListNode* head) {
        if( !head )
        {
         return head;
        }
  
    .............................................
        return 頭指針;
    }
};

第三步:給框架裏面填上語句塊。發揮( if,while,for…)語句的作用,語句其實就是思考邏輯的實現。

原地反轉鏈表的邏輯就是把鏈表的數值比如-1-2-3-4-5-變成-5-4-3-2-1-。這裏設置三個指針 ,前後中分別用cur,pre和next來表示。

1 填入 這塊代碼,使用while 語句做不斷重複做兩件事。

第1件事:使得當前結點的後繼結點變成前驅結點,也就是2的後面不連3,要連1。用這句代碼來實現這件事:cur->next = pre;

第2件事:不斷推動三個指針向後走。用這三句代碼來實現。
1next = cur->next; …(第一件事)…2 pre = cur; 3 cur = next;
大家都看出來了這三句是有順序的。進入循環時一定要先把cur->next保存起來,使next先後移一步,不然下一步cur的後繼結點的改變會讓next指向亂掉。然後前指針和當前指針一起向後移動。

        
        while ( cur )
		{
			next = cur->next; 
			cur->next = pre;  //使當前結點的後繼結點變成前驅結點。

			pre = cur;
			cur = next;
		}

第四步:摳細節,這裏給加上定義,附上初值。

1 給變量加上定義+賦值。

        ListNode* pre = nullptr;
		ListNode* cur = head;
		ListNode* next = nullptr;

此題總結:

這道題目最大的難點就在於拆分語句的四句代碼 ,怎樣安排三指針的移動順序,還有就是進入循環體就一定要先把當前結點的後繼結點保存起來。

算法題經驗:

我做算法題是先搞清楚題意,安排總框架,然後把解決辦法拆分成一個個步驟,再把每個步驟落實到代碼塊,最後填充細節。

這樣可以保證算法題做下來的整個過程中我們的整個思路是清晰的,不會讓看似複雜的算法在我們的大腦中留下壞印象,使我們喪失興趣。

其實做算法題的過程也是在考驗我們的大腦日常解決問題的能力,懂不懂得將生活中碰到的難題拆分,一一解決。

上一篇 從尾到頭打印鏈表(第一種情況 不允許原地打印鏈表)

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