LeetCode234_PalindromeLinkedList (判斷是否為迴文連結串列) Java題解
阿新 • • 發佈:2019-01-22
題目:
Given a singly linked list, determine if it is a palindrome.
Follow up:
Could you do it in O(n) time and O(1) space?
判斷一個連結串列是不是迴文的,這裡要求O(n)時間複雜度和O(1)的空間時間複雜度,總共想了三種辦法,三種辦法都用到了兩個指標,符合題目要求的只有最後一種。
第一種辦法:用陣列倒著存前半段的連結串列的值,然後和後半段連結串列的值進行比較。這種解法執行的時間最久可能是因為陣列倒著插入比較耗時。
程式碼:
第二種解法:在第一種的思路的基礎上,我們要實現一個倒序,我們幹嘛不用現成的資料結構-棧,於是把連結串列前半段壓棧,然後出棧和後面的連結串列依次比較,這種執行時間最短,但因為用到了棧還是不符合題目要求。//用陣列實現 o(n/2)空間 public static boolean isPalindrome(ListNode head) { // ArrayList<Integer> nodeVal=new ArrayList<>(); LinkedList<Integer> nodeVal=new LinkedList<>(); if(head==null||head.next==null) return true; ListNode slow=head; ListNode fast=head; nodeVal.add(0,slow.val); while(fast.next!=null&&fast.next.next!=null) { fast=fast.next.next; slow=slow.next; nodeVal.add(0,slow.val); } ListNode cur=slow; if(fast.next!=null)//連結串列長度為偶數 cur=slow.next; int i=0; while(cur!=null) { if(nodeVal.get(i)!=cur.val) return false; cur=cur.next; i++; } return true; }
程式碼:
//用棧實現 public static boolean isPalindrome2(ListNode head) { Stack<ListNode> stack=new Stack<>(); ListNode slow=head; ListNode fast=head; if(fast==null||fast.next==null)//0個節點或是1個節點 return true; stack.push(slow); while(fast.next!=null&&fast.next.next!=null) { fast=fast.next.next; slow=slow.next; stack.push(slow); } if(fast.next!=null)//連結串列長度為偶數 slow=slow.next; ListNode cur=slow; while(cur!=null) { if(cur.val!=stack.pop().val) return false; cur=cur.next; } return true; }
第三種:我們這樣想,我們可不可以不借助外在的儲存實現倒序呢,其實是可以的,連結串列反轉的時候我們就沒有藉助外在儲存。思路是把後半段的原地連結串列反轉然後和前半段進行比較(當然你也可以反轉前半段)執行時間稍微比第二種慢一些,但是符合題目O(1)空間複雜度的要求
程式碼:
//連結串列原地轉置實現o(1)空間複雜度 public static boolean isPalindrome3(ListNode head) { ListNode slow=head; ListNode fast=head; if(fast==null||fast.next==null)//0個節點或是1個節點 return true; while(fast.next!=null&&fast.next.next!=null) { fast=fast.next.next; slow=slow.next; } //對連結串列後半段進行反轉 ListNode midNode=slow; ListNode firNode=slow.next;//後半段連結串列的第一個節點 ListNode cur=firNode.next;//插入節點從第一個節點後面一個開始 firNode.next=null;//第一個節點最後會變最後一個節點 while(cur!=null) { ListNode nextNode=cur.next;//儲存下次遍歷的節點 cur.next=midNode.next; midNode.next=cur; cur=nextNode; } //反轉之後對前後半段進行比較 slow=head; fast=midNode.next; while(fast!=null) { if(fast.val!=slow.val) return false; slow=slow.next; fast=fast.next; } return true; }