方法一:使用双指针、反转链表求解(推荐)
如果一个链表为回文结构,则链表的前半段和后半段是对称的。
1、利用两个指针(快指针、慢指针),快指针每次移动两个结点,慢指针每次移动一个结点,可以得到链表的中间结点;
2、得到链表的中间结点,从中间结点开始将后续的链表进行反转;
3、比较链表前半段和后半段的值是否对称。
时间复杂度:o(n)
空间复杂度:o(1)
class Solution { public: //反转链表 ListNode* reverse(ListNode* phead) { ListNode* ptemp = nullptr; while (phead) { ListNode* pnext = phead->next; phead->next = ptemp; ptemp = phead; phead = pnext; } return ptemp; } bool isPail(ListNode* head) { //特殊情况处理 if (head == nullptr || head->next == nullptr) return true; ListNode* slow = head; ListNode* fast = head; //得到链表的中点 while (fast != nullptr && fast->next != nullptr) { slow = slow->next; fast = fast->next->next; } //从链表中点开始反转链表 ListNode* pend = reverse(slow); //前半段链表和后半段链表进行对比是否对称 while (pend != nullptr) { if (pend->val != head->val) return false; pend = pend->next; head = head->next; } return true; } };
方法二:利用栈求解
利用栈先进后出的特点将链表存进栈中,再对比链表和栈的值即可判断是否为回文结构
时间复杂度:o(n)
空间复杂度:o(n)
class Solution { public: bool isPail(ListNode* head) { //特殊情况处理 if (head == nullptr || head->next == nullptr) return true; stack<ListNode*> sk; ListNode* ptemp = head; while (ptemp) { sk.push(ptemp); ptemp = ptemp->next; } while (head) { if((head->val) != (sk.top()->val)) return false; head = head->next; sk.pop(); } return true; } };