LeetCode進階206-反轉鏈表(華爲面試題)

概要

本篇介紹一下關於鏈表結構很基礎的知識,單鏈表反轉。這個知識點一樣常常會被各大公司看成面算題考察算法入門,正巧在最近開源的面試題項目中也看見了。事實上跟上一篇LeetCode進階226-翻轉二叉樹(華爲面試題)同屬於若是不理解則會被面試官鄙視系列。java

華爲面試題-將單向鏈表reverse,如ABCD變成DCBA,只能搜索鏈表一次。

原題

206. Reverse Linked List (Easy)

IReverse a singly linked list.node

Example:面試

Input: 1->2->3->4->5->NULL Output: 5->4->3->2->1->NULL Follow up:算法

A linked list can be reversed either iteratively or recursively. Could you implement both?編碼

206. 反轉鏈表。 (簡單)

反轉一個單鏈表。spa

示例:設計

輸入: 1->2->3->4->5->NULL 輸出: 5->4->3->2->1->NULL 進階: 你可否使用循環和遞歸兩種方法解這道題?3d

  • 分類:鏈表(Linked List)

分析

只搜素一次,即一次循環時間複雜度O(n)。指針

思路設計

根據要求,反轉鏈表的本質思想是將每一個鏈表節點的next指針指向前一個節點。code

方法一:遞歸

遞歸思想的核心是是將一件事情拆分遞歸的「大」事情和實際操做的「小」事情。本題能夠宏觀上想象,把頭節的下一個節點當成一個新的鏈表(能夠簡單的理解爲將一個鏈表分紅頭節點和另外一個「大」節點,以下圖所示),這樣就拆分紅了三件事情一、處理「大」節點(新鏈表),這個鏈表遞歸調用進行反轉;二、「大」節點的指針逆序指向頭節點;三、頭節點自己的指針逆向。

1、頭節點的判空處理
2、聲明bigNode賦值爲頭節點的下一個節點即head.next;
3、遞歸逆序處理「大」節點(除頭節點之外的鏈表);
4、將「大」節點(除頭節點之外的鏈表)的指針指向前一個節點即頭節點;
5、頭節點的指針逆序處理指向空(由於逆序後頭節點成了尾節點);
6、返回「大」節點即逆序後的新鏈表;
複製代碼

方法二:循環(非遞歸)

每次循環時,將當前節點的next節點指向前一個節點的pre節點,循環過程須要保存記錄前一個節點。第一個節點因爲反轉後變成新鏈表的最後一個節點所以第一個節點的前一個節點爲空。

僞代碼:

1、聲明變量preNode存儲前一個節點;
2while循環直到達到鏈表最後一個節點;
  i.聲明變量temp存儲當前節點的next節點;
  ii.當前節點指向前一個節點;
  iii.單次循環後更新preNode爲當前節點;
  iiii.head值更新,單次循環後移動head指針到它的next節點;
3.循環結束,返回最後一次preNode賦值爲尾節點即逆序後鏈表的頭節點;
複製代碼

編碼實踐

遞歸實現

public ListNode reverseList(ListNode head) {
        if(head == null || head.next == null) {
            return head;
        }
        ListNode bigNode = head.next;
        ListNode node = reverseList(bigNode);
        bigNode.next = head;
        head.next = null;
        return node;
    }
複製代碼

循環實現

public ListNode reverseList(ListNode head) {
        ListNode preNode = null;
        while(head != null){
            ListNode temp = head.next;
            head.next = preNode;
            preNode = head;
            head = temp ;
        }
        return preNode;
    }
    
複製代碼

結語

華爲面試題中的鏈表是一道鏈表相關的基礎知識題,核心考察的是對鏈表節點指針的理解。最後若是以爲本篇對你有所幫助,給個贊吧~

關注訂閱號 獲取更多幹貨~
相關文章
相關標籤/搜索