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

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

這是悅樂書的第196次更新,第202篇原創

01 看題和準備

今天介紹的是LeetCode演算法題中Easy級別的第58題(順位題號是234)。給出一個單鏈表,確定它是否是迴文。例如:

輸入:1-> 2

輸出:false

輸入:1-> 2-> 2-> 1

輸出:true

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

02 第一種解法

獲取原連結串列反轉後的新連結串列,然後使用迴圈,依次比較兩個連結串列的節點是否相等。反轉連結串列可以藉助之前一道反轉單鏈表的題目,可以直接拿過來用。

public boolean isPalindrome(ListNode head) {
    if (head == null || head.next == null) {
        return true;
    }
    ListNode result = reverseList(head);
    while (head != null && result != null) {
        if (head.val != result.val) {
            return false;
        }
        head = head.next;
        result = result.next;
    }
    return true;
}

public ListNode reverseList(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;
}

03 第二種解法

利用棧先進後去的特點,先將head的每個節點入棧,然後迴圈判斷head的節點值和出棧的值是否相等,只要不相等即可返回false。

public boolean isPalindrome2(ListNode head) {
    if (head == null || head.next == null) {
        return true;
    }
    ListNode newHead = new ListNode(-1);
    newHead.next = head;
    Stack<Integer> stack = new Stack<>();
    while (newHead.next != null) {
        stack.push(newHead.next.val);
        newHead.next = newHead.next.next;
    }
    while (head != null && !stack.isEmpty()) {
        if (head.val != stack.pop()) {
            return false;
        }
        head = head.next;
    }
    return true;
}

04 第三種解法

先使用雙指標同時遍歷head節點,找到中間節點的位置,然後將剩下的部分進行反轉,然後比較head和反轉後的另一半節點值,如果不相等,則說明它不是迴文連結串列。

此解法的時間複雜度是O(n),空間複雜度是O(1)。

public boolean isPalindrome3(ListNode head) {
    ListNode fast = head;
    ListNode slow = head;
    while (fast != null && fast.next != null) {
        fast = fast.next.next;
        slow = slow.next;
    }
    if (fast != null) {
        slow = slow.next;
    }
    slow = reverse(slow);
    fast = head;
    while (slow != null) {
        if (fast.val != slow.val) {
            return false;
        }
        fast = fast.next;
        slow = slow.next;
    }
    return true;
}

public ListNode reverse(ListNode head) {
    ListNode prev = null;
    while (head != null) {
        ListNode next = head.next;
        head.next = prev;
        prev = head;
        head = next;
    }
    return prev;
}

05 第四種解法

此解法是利用遞迴,先宣告一個全域性變數head1,然後將head1指向head,利用遞迴獲取到head的最後一個節點,然後和head1的第一個節點開始比較,不相等就依次向上返回。如果相等,head1指向其下一個節點,然後和head的上一層節點相比,判斷是否相等。

ListNode head1;

public boolean isPalindrome4(ListNode head) {
    if(head==null || head.next==null){
        return true;
    }
    head1=head;
    return palin(head);

}

private boolean palin(ListNode last) {
    if (last.next == null) {
        return last.val == head1.val;
    }
    boolean val = palin(last.next);
    if (!val) {
        return val;
    }
    head1 = head1.next;
    val = head1.val == last.val;
    return val;
}

06 小結

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

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