234.回文链表
题目描述:
请判断一个链表是否为回文链表。
示例 1:
输入: 1->2
输出: false
示例 2:
输入: 1->2->2->1
输出: true
进阶:
你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题?
思想:
快慢指针
用2个指针,一个slow,一个fast,fast是slow的2倍,所以可以达到2分链表的效果,在移动指针时同时对前半部分链表进行反转。最后直接比较被分开的2个链表
因为不能改变当前slow的next,不然就无法跳到下一个元素,所以这里用pre和prepre实现指针的反转
时间复杂度:第一个循环O(n/2),第2个循环O(n/2)
代码:
/** * 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) { if(head==nullptr || head->next==nullptr) //注意初始判定条件 return true; ListNode *pre=nullptr,*prepre=nullptr,*fast=head->next,*slow=head; //pre,prepre要初始化为空指针 while(fast!=nullptr && fast->next!=nullptr){ pre = slow; slow = slow->next; fast = fast->next->next; pre->next = prepre; //翻转指针 prepre = pre; } ListNode *p2 = slow->next; slow->next = pre; ListNode *p1 = fast == nullptr?slow->next:slow; //列表size奇数与偶数对应不同操作 while(p1!=nullptr){ if(p1->val!=p2->val) return false; p1 = p1->next; p2 = p2->next; } return true; } };