算法-判斷鏈表是否爲迴文鏈表

算法-判斷鏈表是否爲迴文鏈表

1、判斷鏈表是否爲迴文鏈表

題目來源:Leetcode234,是一道easy題。

請判斷一個鏈表是否爲迴文鏈表。

示例 1:

輸入: 1->2
輸出: false
示例 2:

輸入: 1->2->2->1
輸出: true
進階:
你能否用 O(n) 時間複雜度和 O(1) 空間複雜度解決此題?

來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/palindrome-linked-list
著作權歸領釦網絡所有。商業轉載請聯繫官方授權,非商業轉載請註明出處。

我們知道單向鏈表只有指向後面的指針,所以不能像數組那樣,從兩端向中間遍歷,不過。

很自然的,我們可以利用棧的性質來存儲鏈表,然後彈出和原鏈表比較,時空複雜度爲N/N

    /**
     * 用棧性質實現
     * @param head
     * @return
     */
    public boolean isPalindrome(ListNode head){
        Stack<ListNode> stack=new Stack<>();
        ListNode curr=head;
        while (curr!=null){
            stack.push(curr);
            curr=curr.next;
        }
        while (head!=null){
            if(head.val!=stack.pop().val){
                return false;
            }
            head=head.next;
        }
        return true;
    }

然而,面試官一般不會就這樣放過我們,讓我們在時空複雜度上進行優化。從時間複雜度上來說,已經做到了2*N(入棧出棧),這題目也不可能用二分法優化的log(n),所以,我們可以從空間複雜度上入手。

迴文字符的定義是什麼?圍繞着中點對稱,由此,我們可以先找到鏈表的中點,把鏈表分爲兩部分,這兩部分是逆序排列的,於是,我們可以將前一段鏈表反轉,然後和後一段鏈表進行比較!

涉及到的知識
1、鏈表反轉問題,在我之前發的文章中有非常詳細的解釋,這裏就不多說了。
2、尋找鏈表中點問題,思路是快慢指針,在前面文章也有解讀

    /**
     * 解題思路:在找中點的時候對前半部分進行翻轉,時空複雜度爲n和1
     * @param head
     * @return
     */
    public boolean isPalindrome(ListNode head){
        if(head==null||head.next==null){
            return true;
        }
        ListNode quick=head;
        ListNode slow=head;

        ListNode prev=null;
        ListNode curr=head;
        while (quick!=null&&quick.next!=null){
            ListNode temp=slow.next;
            quick=quick.next.next;
            slow=slow.next;
            curr.next=prev;
            prev=curr;
            curr=temp;
        }
        if(quick!=null){//奇數個元素,跳過中間節點
            slow=slow.next;
        }
        ListNode frontNode=prev;
        while (frontNode!=null){
            if(frontNode.val!=slow.val){
                return false;
            }
            frontNode=frontNode.next;
            slow=slow.next;
        }
        return true;
    }

值得注意的是,在尋找鏈表中點的過程中,如果鏈表長度爲偶數,慢指針最終指向中點靠後的那個節點,快指針爲null,如果鏈表長度爲奇數,那麼慢指針最終指向正中間的節點,因此,在比較之前需要指向自己的後一個節點。

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