一杯茶,一包烟,一道链表盯一天。
原题如下:

给你一个单链表的头节点 head ,请你判断该链表是否为回文链表。如果是,返回 true ;否则,返回 false 。
你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题?
审题:
题目的描述挺简洁,但是所需要考虑的点还是挺多。那什么是回文链表?在这里就不多描述,我给出几个例子后再总结一下,如下:

只有一个结点的链表属于回文链表。

奇数个结点的链表可能属于回文链表。

偶数个结点的链表也有可能属于回文链表。
如果某个链表按照中间的位置折叠前后两个部分的结点数据元素能够完全重合,这样的链表叫做回文链表。
可能给我们的单链表情况:
1.空的单链表;
2.只有一个结点的单链表;
3.有多个结点,但是是奇数个结点;
4.有多个结点,并且是偶数个结点。
解题思路:
关键点是找中间位置。多个结点时,如果我们找到了链表的中间位置,将前半部分进行反转或者将后半部分进行反转,再逐个比较似乎就变得可行了。反转链表在往期文章中有讲解,这里就不阐述了,现在来看看后面的两种情况。
当单链表有多个结点,并且是偶数个结点时,如下:

当单链表有多个结点,并且是奇数个结点时,如下:

如何确定链表的中间位置?
思路一:
用快慢指针(快慢指针:快指针走两个结点,慢指针走一个结点),当快指针指向最后一个结点时,慢指针所指的位置就是中间结点的位置。
思路二:
先遍历整个单链表,计算出单链表的结点数。结点数除以2,就可以确定第几个结点是中间结点。
两种思路就对应两种解题方案,如果使用快慢指针即思路一,那么适合对链表的后半部分进行反转。如果使用方案二,那么适合对链表的前半部分进行反转。先来看看大家都更能够理解的反转前半部分。
一.反转前半部分
分析:
利用思路二找出两个链表的中间结点位置,如下红色箭头所指结点:

当链表是偶数个结点时,我们需要对箭头所指当前位置结点及之前的结点进行反转;当链表是奇数个是,我们需要对箭头所指结点之前的结点进行反转(不包括箭头所指结点)。
但在进行反转之前我们需要将它的后半部分结点标识出来&
本文通过实例讲解如何使用C++判断单链表是否为回文链表,包括反转链表的前半部分和后半部分两种解题思路,涉及O(n)时间复杂度和O(1)空间复杂度的解决方案。
最低0.47元/天 解锁文章
205

被折叠的 条评论
为什么被折叠?



