LeetCode234 回文链表
请判断一个链表是否为回文链表。
示例 1:
输入: 1->2 输出: false
示例 2:
输入: 1->2->2->1 输出: true
进阶:
你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题?
//章节 - 链表 //三、经典问题 //4.回文链表 /* 算法思想: 利用一个栈,但是这种方法需要O(n) 时间复杂度和 O(n) 空间复杂度。 */ //算法实现: /** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ /* class Solution { public: bool isPalindrome(ListNode* head) { ListNode *p = head; //操作指针 stack<int>S; while (p) { // S.push(p->val); p=p->next; } p = head; // while (p) { if (p->val==S.top()) { S.pop(); p=p->next; } else { return false; } } return true; } }; */ /* 算法思想: 如何代替stack的作用呢,用stack的目的是为了利用其后进先出的特点,好倒着取出前半段的元素。那么现在不用stack了,如何倒着取元素呢。可以在找到中点后,将后半段的链表翻转一下,这样就可以按照回文的顺序比较了。 */ //算法实现: class Solution { public: bool isPalindrome(ListNode* head) { if (!head || !head->next) //为空返回false return true; ListNode *slow = head, *fast = head; while (fast->next && fast->next->next) { //用快慢指针找到中点 slow = slow->next; fast = fast->next->next; } ListNode *last = slow->next, *pre = head; //last指向中点,pre指向头结点 while (last->next) { //将后半段的链表翻转 ListNode *tmp = last->next; last->next = tmp->next; tmp->next = slow->next; slow->next = tmp; } while (slow->next) { //前半段和后半段逐个比较 slow = slow->next; if (pre->val != slow->val) return false; pre = pre->next; } return true; } };