回文链表
- 1.题目来源
- 2.题目描述
- 3.解题思路
- 4.代码展示
所属专栏:玩转数据结构题型
博主首页:初阳785
代码托管:chuyang785
感谢大家的支持,您的点赞和关注是对我最大的支持!!!
博主也会更加的努力,创作出更优质的博文!!
关注我,关注我,关注我,重要的事情说三遍!!!!!!!!
1.题目来源
回文链表
2.题目描述
给定一个链表的 头节点 head ,请判断其是否为回文链表。
如果一个链表是回文,那么链表节点序列从前往后看和从后往前看是相同的。
3.解题思路
这个题目需要结合之前的几个解题思路。
1.快慢指针
2.查找中间节点
3.反转链表
既然我们要判断是否是回文数,如果他是个数组的话我们就会创建两个变量,一个从头出发,一个从尾出发,一次迭代判断是否相同,这样的话就很好的解决了问题。
但是这里是链表,链表的特点就是它是单向的,你只能找到后一个,但是你找不到前面一个。
那我们就想一下有没有方法可以实现类似于数组的方法呢?
我们先观察一下回文的特点:
我们会发现如果是偶数的话左边一半会等于右边一半反转之后的样子。
既然我们不能从尾向头遍历,那我们不妨把后半部分反战过来,让它的尾做头,这样子我们就可以遍历并判断力。
于是我们就得先找到中间节点,并从中间节点开始反转一中间节点尾起点的链表。
反转的时候我们得创建一个新的节点newNode,然后头插反转链表:
但是我们不要忘记了虽然我们反转链表了,但是上面的3的next还是指向下面3的地址的:
将他变成这个样子之后,我们就可以遍历我们的head->val是否等于newNode->val来判断是否是回文链表了。
只要head或者newNode其中一个遍历到了NULL就停止。
4.代码展示
bool isPalindrome(struct ListNode* head)
{
//1.找中间节点
//快慢指针
struct ListNode*fast=head,*low=head;
while(fast && fast->next)//快慢指针退出条件(当链表是偶数后者是奇数的时候)
{
low=low->next;
fast=fast->next->next;
}
struct ListNode* midNode=low;
//2.反转中间节点以后的链表
struct ListNode* newNode=NULL,*midNext=NULL;
while(midNode)
{
midNext=midNode->next;
midNode->next=newNode;
newNode=midNode;
midNode=midNext;
}
//3.迭代判断是否相同
while(head && newNode)//这里同样的链表可能是偶数也可能是奇数,不知道谁先到达NULL
{
if(head->val != newNode->val)
return false;
head=head->next;
newNode=newNode->next;
}
return true;
}