234.回文链表

题目描述:

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

示例 1:

输入: 1->2
输出: false
示例 2:

输入: 1->2->2->1
输出: true
进阶:
你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题?

 

思想:

快慢指针

用2个指针,一个slow,一个fast,fast是slow的2倍,所以可以达到2分链表的效果,在移动指针时同时对前半部分链表进行反转。最后直接比较被分开的2个链表
因为不能改变当前slow的next,不然就无法跳到下一个元素,所以这里用pre和prepre实现指针的反转
时间复杂度:第一个循环O(n/2),第2个循环O(n/2)

 

代码:

/**
 * 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==nullptr || head->next==nullptr)  //注意初始判定条件
            return true;
        ListNode *pre=nullptr,*prepre=nullptr,*fast=head->next,*slow=head;  //pre,prepre要初始化为空指针
        while(fast!=nullptr && fast->next!=nullptr){
            pre = slow;
            slow = slow->next;
            fast = fast->next->next;
            pre->next = prepre;  //翻转指针
            prepre = pre;    
        }
        ListNode *p2 = slow->next;
        slow->next = pre;
        ListNode *p1 = fast == nullptr?slow->next:slow;   //列表size奇数与偶数对应不同操作
        while(p1!=nullptr){
            if(p1->val!=p2->val)
                return false;
            p1 = p1->next;
            p2 = p2->next;
        }
        return true;
    }
};

 

posted @ 2020-05-01 00:58  thefatcat  阅读(97)  评论(0编辑  收藏  举报