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