【LeetCode & 剑指offer刷题】链表题11:Palindrome Linked List

【LeetCode & 剑指offer 刷题笔记】目录(持续更新中...)

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.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
/*
问题:判断是否为回文链表
方法:用快慢指针法找到链表中部位置,然后翻转右半链表,判断右边链表与左边链表是否相等
O(n),O(1)
*/
class Solution {
public:
    bool isPalindrome(ListNode* head)
    {
        if (!head || !head->next) return true; //异常情况处理,为空结点或者一个结点时     
       
        ListNode *slow = head, *fast = head;
        while (fast && fast->next) //快慢指针法,让slow指向链表中部位置
        {
            slow = slow->next;
            fast = fast->next->next;
        }//退出时,fast为最后一个结点或者nullslow处在中间位置(与结点数有关,左子链表head~slow-1, 右子链表为slow~end,右子链表比左子链表长一或者相等)
        //例:0~10,slow 5, fast 10; 0~9,slow5,fast null (0表示头结点,slowfast的起点)
       
        ListNode* right = reverseList(slow);//反转右边链表
        ListNode* left = head;
       
        while(left && right)//比较左右子链表是否相等
        {
            if(left->val == right->val)
            {
                left = left->next;
                right = right->next;
            }
            else
                return false;
           
        }
       
        return true;
       
    }
    //函数:反转链表
    ListNode* reverseList(ListNode* head)
    {
        if(head == nullptr) return nullptr;
      
        ListNode *pre = nullptr, *cur = head,*next; //三个指针分别保存之前,当前,下一个结点
        while(cur)
        {
            next = cur->next; //保存原链表该结点的下一个结点,以免变换指向之后无法遍历到下一个结点
            cur->next = pre; //变换指向
          
            pre = cur; //更新指针
            cur = next; //更新指针
        }
        return pre; //最后pre指向最后一个结点,cur指向null
    }
};
 

 

posted @ 2019-01-05 16:57  wikiwen  阅读(138)  评论(0编辑  收藏  举报