1. 程式人生 > >234. Palindrome Linked List(python+cpp)

234. Palindrome Linked List(python+cpp)

題目:

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?

解釋: 判斷一個;連結串列是不是迴文,但是連結串列的指標並不能翻轉,怎麼辦呢/ 利用快慢指標先找到中間的位置(假設連結串列長度為n,則slow指向的是n/2+1(index從1開始),也就是後半段的 第一個結點),把連結串列從中間位置開始翻轉,再兩個指標,一個指向mid一個指向head,開始遍歷,如果每個值都一樣的話說明是迴文。需要考慮連結串列的長度是奇數或者偶數的情況。 額,當然也可以把連結串列的元素儲存到一個數組中,再判斷是不是迴文,但是這樣的話空間複雜度就不是 O(1)了 python程式碼:

# Definition for singly-linked list.
# class ListNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution(object):
    def isPalindrome(self, head):
        """
        :type head: ListNode
        :rtype: bool
        """
        if not head or not
head.next: return True slow,fast=head,head middle_pre=slow while fast and fast.next: middle_pre=slow slow=slow.next fast=fast.next.next #middle_pre儲存第一部分的最後一個結點 p=middle_pre.next cur_pre=None while
p: cur_next=p.next p.next=cur_pre cur_pre=p p=cur_next middle_pre.next=cur_pre p_middle=middle_pre.next p_head=head while p_head!=middle_pre.next: if p_head.val!=p_middle.val: return False p_head=p_head.next p_middle=p_middle.next return True

c++程式碼:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    bool isPalindrome(ListNode* head) {
        if (!head ||!head->next)
            return true;
        ListNode *fast=head,*slow=head;
        //middle_pre指向前半段的最後一個元素
        ListNode *middle_pre=slow;
        while(fast &&fast->next)
        {
            middle_pre=slow;
            slow=slow->next;
            fast=fast->next->next;
        }
        //原地翻轉後半部分連結串列的工作指標
        ListNode*cur=middle_pre->next;
        ListNode*cur_pre=NULL;
        //下面是原地翻轉單鏈表的經典寫法
        while(cur)
        {
            ListNode*cur_next=cur->next;
            cur->next=cur_pre;
            cur_pre=cur;
            cur=cur_next;
        }
        //此時,cur_pre儲存翻轉後的連結串列的頭結點,這裡是合併
        middle_pre->next=cur_pre;
        //接下來是比較,注意,後半段的元素有可能比前半段的元素多一個
        //所以while迴圈的第一個條件是必須的
        ListNode* p_head=head;
        ListNode* p_middle=cur_pre;
        while(p_head!=middle_pre->next)
        { 
            if(p_head->val!=p_middle->val)
                return false;
            p_head=p_head->next;
            p_middle=p_middle->next;
        }
        return true;
    }
};

總結: 注意最後比較的時候的判斷條件只有一個即可,因為後半段的個數肯定>=前半段個數。