1. 程式人生 > >LeetCode演算法題-Reverse Linked List(Java實現)

LeetCode演算法題-Reverse Linked List(Java實現)

這是悅樂書的第192次更新,第195篇原創

01 看題和準備

今天介紹的是LeetCode演算法題中Easy級別的第51題(順位題號是206)。反轉單鏈表。例如:

輸入:1-> 2-> 3-> 4-> 5
輸出:5-> 4-> 3-> 2-> 1

本次解題使用的開發工具是eclipse,jdk使用的版本是1.8,環境是win7 64位系統,使用Java語言編寫和測試。

02 第一種解法

先利用遞迴函式,進入到最後一個節點的位置,此時需要反轉指標所指向的引用方向,比如原來是n(k)-->n(k+1),現在需要反轉過來變成n(k+1)-->n(k),此時需要n(k).next.next = n(k),將n(k+1)的下一個節點指向n(k),同時需要將原來n(k)節點的下一個節點指向null,即n(k).next = null。如果不指向null,會形成環,造成死迴圈。

public ListNode reverseList(ListNode head) {
    if (head == null || head.next == null) {
        return head;
    }
    ListNode p = reverseList(head.next);
    head.next.next = head;
    head.next = null;
    return p;
}


03 第二種解法

在遍歷列表時,將當前節點的下一個指標更改為指向其上一個元素。由於節點沒有引用其前一個節點,因此必須事先儲存其前一個元素。在更改引用之前,還需要另一個指標來儲存下一個節點。最後返回新的連結串列。

public ListNode reverseList2(ListNode head) {
    ListNode result = null;
    ListNode current = head;
    while (current != null) {
        ListNode pre = current.next;
        current.next = result;
        result = current;
        current = pre;
    }
    return result;
}


04 第三種解法

利用HashMap,依次遍歷head節點,將下一個節點作為key、當前節點作為value存入其中,直到其最後一個節點。新建立一個節點指向head的最後一個節點,然後開始從map中取出key所對應的value作為新節點的下一個節點。

public ListNode reverseList3(ListNode head) {
    if (head == null || head.next == null) {
        return head;
    }
    HashMap<ListNode, ListNode> nodeMap = new HashMap<>();
    ListNode curr = head;
    int leng = 0;
    while (curr.next != null) {
        nodeMap.put(curr.next, curr);
        ++leng;
        curr = curr.next;
    }
    ListNode newHead = curr;
    for (int i = 0; i < leng; i++) {
        curr.next = nodeMap.get(curr);
        curr = curr.next;
    }
    curr.next = null;
    return newHead;
}


05 第四種解法

使用棧,藉助其先進後出的特點,先將head的每一個節點入棧,然後新建一個節點res,每次出棧的節點,獲取其節點值val,然後建立新的節點作為res的下一個節點。

public ListNode reverseList4(ListNode head) {
    if (head == null || head.next == null) {
        return head;
    }
    Stack<ListNode> stack = new Stack<>();
    while (head != null) {
        stack.push(head);
        head = head.next;
    }
    ListNode res = new ListNode(-1);
    ListNode temp = res;
    while (!stack.isEmpty()) {
        temp.next = new ListNode(stack.pop().val);
        temp = temp.next;
    }
    return res.next;
}


06 第五種解法

此解法與第四種解法思路類似,只不過是將棧換成了陣列,然後新建node節點,以陣列最後一位元素作為節點值,然後開始迴圈處理每個新的節點。

public ListNode reverseList5(ListNode head) {
    if (head == null || head.next == null) {
        return head;
    }
    ArrayList<Integer> list = new ArrayList<Integer>();
    while (head != null) {
        list.add(head.val);
        head = head.next;
    }
    ListNode node = new ListNode(list.get(list.size()-1));
    ListNode last = node;
    for (int i=list.size()-2; i >= 0; i--) {
        ListNode temp = new ListNode(list.get(i));
        last.next = temp;
        last = last.next;
    }
    return node;
}


07 小結

演算法專題目前已連續日更超過一個月,演算法題文章51+篇,公眾號對話方塊回覆【資料結構與演算法】、【演算法】、【資料結構】中的任一關鍵詞,獲取系列文章合集。

以上就是全部內容,如果大家有什麼好的解法思路、建議或者其他問題,可以下方留言交流,點贊、留言、轉發就是對我最大的回報和支援!