题目
思路
判断单链表链表回文不能和判断数组回文一样,因为数组很容易找到前一个元素,但是单链表没办法找到上一个节点,所以这道题有一个投机取巧的思路:将链表放在数组中,通过双指针遍历数组是否回文。这个思路比较简单感兴趣的可以自己实现。
这里提供一个新思路:寻找中间节点+反转链表
既然单链表不能找到前一个节点,那我们可以先将链表反转,在依次寻找后一个节点,再判断翻转后的节点是不是和最开始的节点是一样的
如何翻转链表可以看这篇文章syseptember的个人博客:反转链表
如何找链表中间节点可以看这篇文章syseptember的个人博客:寻找链表中间节点
注意:这里反转链表没有真正的在原链表基础上动刀子,而是新构造了一个链表,新链表是翻转后的链表
代码
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
typedef struct ListNode ListNode;
struct ListNode* reverseList(struct ListNode* head)
{
if (head == NULL || head->next == NULL) return head;
struct ListNode* newhead = NULL;
struct ListNode* cur = head;
struct ListNode* nextnode = head->next;
while (cur)
{
cur->next = newhead;
newhead = cur;
cur = nextnode;
if (nextnode)
nextnode = nextnode->next;
}
return newhead;
}
struct ListNode* middleNode(struct ListNode* head){
if (head == NULL || head->next == NULL) return head;
struct ListNode* fast = head, *slow = head;
while (fast && fast->next)
{
slow = slow->next;
fast = fast->next->next;
}
return slow;
}
bool isPalindrome(struct ListNode* head){
ListNode* mid = middleNode(head);
ListNode* rmid = reverseList(mid);
while (rmid)
{
if (head->val != rmid->val) return false;
else
{
head = head->next;
rmid = rmid->next;
}
}
return true;
}