牛客算法–第六章
题目二
判断一个链表是否为回文结构
【题目】
给定一个链表的头节点 head,请判断该链表是否为回文结构。
例如:
1->2->1,返回 true。
1->2->2->1,返回 true。
15->6->15,返回 true。
1->2->3,返回 false。
【要求】
如果链表长度为 N,时间复杂度达到 O(N),额外空间复杂度达到 O(1)
总结,这道链表题是来考指针的操作。实话说,其实面试时候的每道链表题都是用来考指针的操作。
先讲,麻烦的操作,面试的时候不推荐。
第一种:学过C++中的STL的话,应该知道,List容器,这里判断链表是否为回文结构,可以简单粗暴的。
List<int> list1,list2;
假设list1中存储的就是原来的链表。
那么,直接调用<algorithm>中的reverse算法
即reverse(list2.begin(),list2.end());
然后直接比较 list1==list2?就可以。
第二种:其实和第一种方法,本质是一样的,就是想要用到逆序,然后进行比较,谈到逆序,自然也可以用数据结构栈来实现。那么这样的话,就又可以有两种子方案,就是可以入栈整个链表,也可以入栈半个链表。
第三种就是面试的时候想要考查的操作链表指针的算法:
假设数据:
1->2->3->2->1->null
我们的目标是将其变为以下结构:
null
1->2->3<-2<-1
其中令链表中间结点mid->null,也就是3的位置。
那么,如何操作呢?
使用快慢指针,list1一次走一步,list2一次走两步。
等到list2走到链表尾的时候,list1正好走到链表的中间位置,也就是mid。然后就是将链表的后半段进行逆序。完成以上结构的变形。
关键点,就是需要记录mid,和last,也就是链表中间和末尾的位置。链表的问题都需要注意防止出现断裂的现象。
还有一个关键点就是变形完成之后的遍历终止条件
l=head,r=last;
while(l!=null && r!=null)