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

Follow up:
Could you do it in O(n) time and O(1) space?
题目描述比较简单:判断链表中的val组成的数字是否是回文数即形如12321 123321即是回文数。
如果题目中没有O(1) space的要求的话,那么可以把链表的值顺序读出放在数组中,然后进行判断。
一种比较巧妙的思路是:逆序(reverse)后半段,然后比较前后两段的值是否相同。
实现代码:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */

struct ListNode* reverseList(struct ListNode* head) 
{
    if(NULL==head) 
        return head;

    struct ListNode *p=head;
    p=head->next;
    head->next=NULL;
    while(NULL!=p)
    {
        struct ListNode *tmp=p->next;
        p->next=head;
        head=p;
        p=tmp;
    }
    return head;
}

bool isPalindrome(struct ListNode* head) 
{
    if(NULL == head || NULL == head->next)
        return true;
    
    struct ListNode * slow = head;
    struct ListNode * fast = head;
    
    while(fast->next &&fast->next->next)
    {
        fast = fast->next->next;
        slow = slow->next;
    }
    
    slow->next = reverseList(slow->next);
    slow = slow->next;

    while(slow!=NULL)
    {
        if(head->val!=slow->val)
            return false;
            head=head->next;
            slow=slow->next;
    }
    
    return true;
    
}

2021.07.11更新
更好理解的C++代码如下,这里其实修改了链表后半段的顺序,如果不修改链表后半段的顺序,可以新增一个flag,最后返回flag,在程序返回前再将后半段恢复回来。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    bool isPalindrome(ListNode* head) {
        ListNode* fast = head,*slow = head;
        
        while(fast && fast->next && fast->next->next)
        {
            fast = fast->next->next;
            slow = slow->next;
        }
        slow->next = reverse(slow->next);
        ListNode* left = head,*right = slow->next;
        while(left && right)
        {
            if(left->val != right->val)
                return false;
            
            left = left->next;
            right = right->next;
        }

        return true;    
    }
private:
    ListNode* reverse(ListNode* head) {
        ListNode* prev = nullptr,*curr = head;
        while(curr)
        {
            ListNode* nxt = curr->next;
            curr->next = prev;
            prev = curr;
            curr = nxt;
        }
        return prev;
    }
};

运行效率:

执行用时:200 ms, 在所有 C++ 提交中击败了95.26%的用户
内存消耗:115.3 MB, 在所有 C++ 提交中击败了48.11%的用户