2-7迴文鏈表

題目描述

  • 判斷一個鏈表是否爲迴文結構
  • 例如 1 2 1 返回true,1 2 3 返回false。

解題方法1

  • 可以使用棧來解決,首先遍歷鏈表求表長。然後將鏈表前一半節點元素依次入棧,然後再依次出棧與後續遍歷節點進行比較。
  • 如果是奇數忽略中間節點。
  • 此種方式時間複雜度爲n,空間複雜度也爲n。
public class Test {
    public static void main(String[] args) throws Exception {
         int[] arr = {11,22,11};
         Node head = create(arr);
        boolean flag = ishuiwen(head);
        System.out.println(flag);
    }
   public static boolean ishuiwen(Node head){
        if(head.next==null){
            return true;
        }
        int len = 0;
        for(Node p=head.next;p!=null;p=p.next){
            len++;
        }
        int i=1;
        Stack<Integer> s = new Stack<>();
        for(Node p=head.next;i<=len;p=p.next){
            if(i<=len/2){
                s.push(p.val);
            }
            else{
                if(len%2==1 && i==len/2+1){
                     i++;
                     continue;
                }
                if(s.pop() !=p.val){
                    return false;
                }
            }
            i++;
        }
        return true;
   }

    //創建單鏈表
    public static Node create(int[] arr){
        Node head = new Node(0); //頭節點
        Node newnode = null; //指向新節點
        Node tail = head; //指向鏈表尾節點
        for(int a:arr){
            newnode = new Node(a);
            newnode.next = tail.next;
            tail.next = newnode;
            tail = newnode;
        }
        return head;
    }
}
class Node{
    int val;
    Node next;
    Node(int val){
        this.val = val;
    }
}

解題方法2

  • 上述解法空間複雜度爲n。還有優化的空間。
  • 我們可以先將鏈表的右半區反轉,然後依次比較檢查迴文,最後再將鏈表還原。
  • 如 1 2 3 2 1 反轉後爲 1 2 3 1 2
  • 1 2 3 3 2 1 反轉後爲 1 2 3 1 2 3
  • 具體反轉操作把中間節點作爲頭節點依次頭插即可。
public class Test {
    public static void main(String[] args) throws Exception {
        int[] arr = {11,22,33,22,11};
        Node head = create(arr);
        boolean flag = ishuiwen(head);
        System.out.println(flag);
    }
   public static boolean ishuiwen(Node head){
        if(head.next==null || head.next.next==null){
            return true;
        }
        //求鏈表長度
        int len=0;
        for(Node p=head.next;p!=null;p=p.next){
            len++;
        }
       //找鏈表中間節點
       Node midnode = head; //指向僞頭節點(鏈表中間位置) 如果len爲奇數將第len/2+1個節點作爲僞頭節點
        for(int i=1;i<=len;i++){
            if(i<=(len/2+len%2)){
                midnode = midnode.next;
            }
            else{
                break;
            }
        }
        //反轉鏈表右半段
        Node p=midnode.next;
        midnode.next=null;
        while(p!=null){
            Node temp =p.next;
            p.next = midnode.next;
            midnode.next=p;
            p=temp;
        }
        //驗證鏈表是否爲迴文鏈表
        p = midnode.next;
        Node q = head.next;
        boolean flag = true;
        while(p!=null){
            if(p.val!=q.val){
                flag = false;
            }
            p=p.next;
            q=q.next;
        }
       //還原鏈表
       p=midnode.next;
       midnode.next=null;
       while(p!=null){
           Node temp =p.next;
           p.next = midnode.next;
           midnode.next=p;
           p=temp;
       }
        return flag;
   }
   class Node{
    int val;
    Node next;
    Node(int val){
        this.val = val;
    }
}
  • 雖然進行了5個循環,但是時間複雜度仍爲n,只不過n前面的係數應該爲3。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章