解法一:对后半段进行翻转,再逐个比较
如果此题是判断一个字符串是否为回文结构的话,那么很容易想到:用两个指针,左边的指向头部,右边的只指向尾部,两边同时向中间移动逐字匹配,如果发现有一个没有匹配上那么此串边不是回文结构。
此题使用的是链表,只能从头向尾的方向进行移动,所以不能直接按照上述方法进行匹配。如果想按上述步骤进行,需要将中间到后面的节点间的next反向,这样才能从尾部向中间进行移动。(注:如果该链表是回文结构,那么一定是对称的,所以可以将中间到后面的next指针反向)
/**
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
class Solution {
public:
/**
*
* @param head ListNode类 the head
* @return bool布尔型
*/
ListNode* Reverse(ListNode *head){
ListNode *pre=nullptr;
ListNode *cur=head;
ListNode *nex=nullptr;
while(cur){
nex=cur->next;
cur->next=pre;
pre=cur;
cur=nex;
}
return pre;
}
bool isPail(ListNode* head) {
// write code here
ListNode *slow=head,*fast=head;
//找中点
while(fast&&fast->next){
slow=slow->next;
fast=fast->next->next;
}
//fast不为空说明L为奇数,slow应该后移
if(fast) slow=slow->next;
//反转
slow=Reverse(slow);
fast = head;
while(slow){
if(fast->val!=slow->val) return false;
fast = fast->next;
slow = slow->next;
}
return true;
}
};
这里标注下该过程出现的bug:
把pre和cur的赋值顺序写错了,应该先将pre赋为cur再修改cur,否则就会导致下图中的pre和cur指向同一节点的情况
正确代码如下:
ListNode *Reverse(ListNode *head){
ListNode *pre=nullptr;
ListNode *cur=head;
ListNode *nex=nullptr;
while(cur){
nex=cur->next;
cur->next=pre;
pre=cur;
cur=nex;
}
return pre;
}
解法二:使用栈从后向前遍历
我们知道栈的特点是先进后出,所以将链表中的元素放入栈再取出来就可以实现从后到前的遍历了。对于此题,我们只需要将前半段放入栈中,再逐个将栈顶元素与链表后半段进行比较即可。补充栈的初始化等相关操作,转自链接https://www.cnblogs.com/skywang12345/p/3562239.html
具体实现与上题差不多,用slow和fast找中点(slow每次移动一步,fast每次移动两步,图示如下)
- 若L为奇数,fast->next==nullptr时 slow为中点
- 若L为偶数,fast=nullptr时 slow为中点偏右
若L为奇数,由于slow指向中点与会问的判断无关,所以不应将此节点入栈,在跳过该节点后,slow指向后半段的第一个节点。此时fast重新指向head(即前半段的第一个节点),逐个比较栈顶与链表前半段的节点,比较后记得将栈顶元素出栈,fast后移。
/**
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
class Solution {
public:
/**
*
* @param head ListNode类 the head
* @return bool布尔型
*/
bool isPail(ListNode* head) {
// write code here
ListNode *slow = head, *fast = head;
stack<int> s;
//若L为奇数,fast->next==nullptr时 slow为中点
//若L为偶数,fast=nullptr时 slow为中点偏右
while(fast&&fast->next){
s.push(slow->val);
fast=fast->next->next;
slow=slow->next;
}
//当L为奇数时slow=slow->next,跳过中点比较后半段
if(fast) slow=slow->next;
while(slow){
if(slow->val!=s.top()) return false;
slow=slow->next;
s.pop();
}
return true;
}
};