Loading

LeetCode234 回文链表

请判断一个链表是否为回文链表。

示例 1:

输入: 1->2
输出: false

示例 2:

输入: 1->2->2->1
输出: true

进阶:
你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题?

 


 

 

//章节 - 链表    
//三、经典问题
//4.回文链表
/*
算法思想:
    利用一个栈,但是这种方法需要O(n) 时间复杂度和 O(n) 空间复杂度。
*/
//算法实现:
/**
 * 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) {
        ListNode *p = head;  //操作指针
        stack<int>S;
        while (p) {  //
            S.push(p->val);
            p=p->next;
        }
        p = head;  //
        while (p)
        {
            if (p->val==S.top())
            {
                S.pop();
                p=p->next;
            }
            else {
                return false;
            }
        }
        return true;
    }
};
*/
/*
算法思想:
    如何代替stack的作用呢,用stack的目的是为了利用其后进先出的特点,好倒着取出前半段的元素。那么现在不用stack了,如何倒着取元素呢。可以在找到中点后,将后半段的链表翻转一下,这样就可以按照回文的顺序比较了。
*/
//算法实现:
class Solution {
public:
    bool isPalindrome(ListNode* head) {
        if (!head || !head->next)   //为空返回false
            return true;
        ListNode *slow = head, *fast = head;
        while (fast->next && fast->next->next) {    //用快慢指针找到中点
            slow = slow->next;
            fast = fast->next->next;
        }
        ListNode *last = slow->next, *pre = head;   //last指向中点,pre指向头结点
        while (last->next) {    //将后半段的链表翻转
            ListNode *tmp = last->next;
            last->next = tmp->next;
            tmp->next = slow->next;
            slow->next = tmp;
        }
        while (slow->next) {    //前半段和后半段逐个比较
            slow = slow->next;
            if (pre->val != slow->val) 
                return false;
            pre = pre->next;
        }
        return true;
    }
};

 

posted @ 2018-12-03 22:38  Parzulpan  阅读(97)  评论(0编辑  收藏  举报