1. 程式人生 > 其它 >LeetCode234 迴文連結串列

LeetCode234 迴文連結串列

題目

請判斷一個連結串列是否為迴文連結串列。

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

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

進階: 
你能否用 O(n) 時間複雜度和 O(1) 空間複雜度解決此題? 

方法

棧方法

先計算連結串列長度,若為偶數,將前半個連結串列數值存入棧,後半個連結串列驗證與棧中資料是否一致

  • 時間複雜度:O(n)
  • 空間複雜度:O(n)
class Solution {
    public boolean isPalindrome(ListNode head) {
        if(head==null||head.next==null){
            return true;
        }
        int len = 0;	//獲取連結串列長度
        ListNode node = head;
        while(node!=null){
            len++;
            node = node.next;
        }
        Stack<Integer> stack = new Stack<>();
        node = head;//把前半個連結串列存入棧
        for(int i=0;i<len/2;i++){
            stack.add(node.val);
            node = node.next;
        }
        if(len%2!=0){
            node = node.next; //若為奇數個,跳過中間的數
        }
        while(node!=null){
            if(node.val!=(stack.pop())){
                return false;
            }
            node = node.next;
        }
        if(stack.isEmpty()){
            return true;
        }
        return false;
    }
}

快慢指標法

先計算連結串列長度,將後半個連結串列反轉,然後快指標從中間開始,慢指標從頭開始一一對比,該方法雖然減小了空間複雜度,但需要修改原連結串列

  • 時間複雜度:O(n)
  • 空間複雜度:O(1)
class Solution {
    public boolean isPalindrome(ListNode head) {
        if(head==null||head.next==null){
            return true;
        }
        int len = 0;
        ListNode node = head;
        while(node!=null){
            len++;
            node = node.next;
        }
        node = head;
        for(int i=0;i<len/2;i++){
            node = node.next;
        }
        if(len%2!=0){
            node = node.next;
        }
        ListNode pre = null;
        ListNode next = null;
        while(node!=null){
            next = node.next;
            node.next = pre;
            pre = node;
            node = next;
        }
        node = head;
        while(pre!=null){
            if(pre.val!=node.val){
                return false;
            }
            pre = pre.next;
            node = node.next;
        }
        return true;
    }
}