1. 程式人生 > >LeetCode刷題Easy篇. Palindrome Linked List

LeetCode刷題Easy篇. Palindrome Linked List

題目

Given a singly linked list, determine if it is a palindrome.

Example 1:

Input: 1->2
Output: false

Example 2:

Input: 1->2->2->1
Output: true

Follow up:
Could you do it in O(n) time and O(1) space?

十分鐘嘗試

我想到的是反轉連結串列,然後比較是否相同,寫完程式碼後,發現不行,因為原來的連結串列已經被修改了,無法比較。

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public boolean isPalindrome(ListNode head) {
      ListNode reverseHead=reverseList(head);
        ListNode curr=head;
        ListNode currReverse=reverseHead;
        //如何比較兩個連結串列相等,原來對連結串列,已經被修改了
      while(curr!=null&&currReverse!=null){
          if(curr.val!=currReverse.val){
              return false;
          }
         curr=curr.next;
          currReverse=currReverse.next;
              
      }
         return true;
        
    }
    
    private ListNode reverseList(ListNode head){
          ListNode pre=null;
        ListNode curr=head;
        while(curr!=null){
            ListNode tmp=curr.next;
            curr.next=pre;
            pre=curr;
            curr=tmp;
        }
        //注意返回不是curr,因為curr為空
        return pre;
        
    }
}

怎麼解決呢?不能單獨儲存,因為空間複雜度高。我們是否可以反轉一半,然後和另外一半進行比較,比如1-2--2-1,我們逆轉前半部,判斷和後半部分是否相同,這樣就可以。再來,我們嘗試一下。

我的思路:

1 求出size,因為我需要知道中間節點,也就是反轉操作的尾節點。

2 逆轉前半部分

3,head往後,curr往後,比較是否相同

但是我感覺應該有優化的地方。第一步求size,應該不需要遍歷整個連結串列,這樣效率太低了。嘗試一下,指標到達中間,還需要儲存下面的節點的指標,因為reverse後就丟失了,裡面細節太多,可能還需要考慮奇數偶數。所以參考其他人的方法。

我走兩步,你走一步,我到達終點的時候是不是你剛好走了一半?

設定快慢兩個指標,程式碼如下,如果fast為空並且fast.next為空,則slow位於中間位置,我發現無論奇數偶數都沒有問題,但是作者對奇數進行了slow.next處理。我暫時不考慮這個情況:

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public boolean isPalindrome(ListNode head) {
        //找到中間位置指標,利用快慢指標
     ListNode fast=head;
     ListNode slow=head;
     while(fast!=null&&fast.next!=null){
         //如果偶數個節點,此時fast為空,如果奇數,正好尾部節點
         fast=fast.next.next;
         slow=slow.next;
     }
        ListNode reverseHead=reverseList(slow);
         fast=head;
        while(reverseHead!=null){
          if(fast.val!=reverseHead.val){
              return false;
          }
         fast=fast.next;
         reverseHead=reverseHead.next;
              
      }
         return true;
        
    }
    
    private ListNode reverseList(ListNode head){
        ListNode pre=null;
        ListNode curr=head;
        while(curr!=null){
            ListNode tmp=curr.next;
            curr.next=pre;
            pre=curr;
            curr=tmp;
        }
        //注意返回不是curr,因為curr為空
        return pre;
        
    }
}