目录
温馨提示:由于C语言代码与C++代码目前看起来差异不大,感觉写两种代码在做无用功,所以,后面都只写C语言代码(相信应该都看得懂),等开始写C++方面的知识时,才使用C++的方式编写代码。望谅解^_^。
1.原题链接:
2.双指针:
对于本题,我们可以先使用快慢指针找到链表的中间结点,然后将后半部分结点反转,然后再遍历链表,看前半部分结点与后半部分结点的值是否相等,如果都相等,链表就回文。
寻找中间结点的两种情况:
从上图我们可以看出,要反转链表,我们可以从slow所指结点开始反转:
以下是要反转的部分:
当我们反转链表的时候,前一个结点的next指向未发生改变 :
所以,这里我们需要让前一个结点(可以在寻找中间结点的时候定义一个pre指针来存放前一个结点)的指向改变以下:
最后,再次执行遍历,当左边结点遍历完时,会指向pre->next,此时我们就可以退出,看链表是否为回文链表。
代码实现:
typedef struct ListNode ListNode;
ListNode* reverseList(ListNode* head) {
ListNode* left = NULL;
ListNode* mid = head;
ListNode* right;
while (mid!=NULL)
{
right = mid->next;
mid->next = left;
left = mid;
mid = right;
}
return left;
}
bool isPalindrome(struct ListNode* head) {
if(head==NULL||head->next==NULL)//当是空链表或者是链表只有一个结点时
return true;
ListNode* slow=head;
ListNode* fast=head;
ListNode* pre=NULL;//方便后续连接反转后的链表
while(fast!=NULL&&fast->next!=NULL)//找到中间结点
{
pre=slow;
slow=slow->next;
fast=fast->next->next;
}
//反转链表,如果不知道怎么写,可以去看之前我写的哦O.o
pre->next=reverseList(slow);//连接反转后的链表
ListNode* cur=pre->next;//用于比较前半部分与后半部分链表的值是否相等
while(head!=pre->next)
{
if(head->val!=cur->val)//如果当前遍历到的两个结点的值不同,不是回文
return false;
else
{
head=head->next;
cur=cur->next;
}
}
return true;
}
3.提交结果:
4.读书分享:
《道德经·第四十四章》:
名与身熟亲?身与货熟亲?得与亡熟病?
甚爱必大废;多藏必厚亡。
故知足不辱,知止不殆,可以长久。
解释:
声明和生命比起来哪一样亲切?生命和货利比起来哪一样贵重?得到名利和丧失生命哪一样为害?
过分的爱名就必定要付出重大的耗费;过多的藏货就必定会招致惨重的损失。
所以知道满足就不会受到屈辱,知道适可而止就不会带来危险,这样才可以保持长久。