题目描述: 给你一个单链表的头节点 head ,请你判断该链表是否为回文链表。如果是,返回 true ;否则,返回 false 。 这是一道比较简单的题目,按照回文的定义,要判断是否为回文链表,我们应该从链表的头和尾分别向中间靠拢,判断各对node的值是否都相等,大体思路是这样的。确定好大体思路后,我们开始来思考实现方式。 给题解之前,我想说说我做的过程中的一些想法。由于在做这道题之前,我做过一道回文数组的判断,这两有什么区别呢?无非就是数组头和尾在向中间靠拢的时候,可以直接用下标加减一的方式来实现,而链表(此时是指单链表)却好像只能用 head = head->next 从头向中间靠拢,而没法反方向过来从尾向中间靠拢,所以当时我就想,那我把链表遍历一遍建立一个新的数组,再判断这个数组是否为回文数组不就行了吗?越想越觉得有道理!直到我看见了这个tips.…… 最多10的5次方个节点,意思是如果我要采取这种做法,我初始化要建立的数组至少也要10的5次方,而且……可能这个做法也不是这道题真正想要考的 因此我改变了思路,还是要从链表来入手。当时我是这么想的,既然问题在于我无法从尾向中间靠拢,那我能不能重新建一个链表,让这个链表是跟原链表的右半段是相反的呢,似乎非常的合理。 这个时候我转过来考虑如何创建一个反过来的链表,创建链表其实就是向一个空链表插入一个或多个节点的过程,链表的插入我们有头插法和尾插法(不懂链表头插法与尾插法的请点 这里 ),很明显,头插法刚好可以实现我们的功能,也就是遍历一遍可以生成一个反转过来的链表,到这里我们大概有了一个大体的实现流程,接下来请看下面的代码: 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) {if(head->next == nullptr||head == nullptr)return true;struct ListNode *slow = head;struct ListNode *fast = head;struct ListNode *rhead = nullptr;struct ListNode *store;while(fast->next != nullptr && fast->next->next != nullptr){slow = slow->next;fast = fast->next->next;}slow = slow->next; while(temp != nullptr){store = slow->next;slow->next = rhead;rhead = slow;slow = store;}while(rhead != nullptr){if(rhead->val != head->val)return false;rhead = rhead->next;head = head->next;}return true;} }; 关于原地反转链表的算法大家可以看一下这篇文章,讲得很棒! 谢谢大家的阅读,有什么问题请在评论区评论