【LeetCode & 剑指offer 刷题笔记】目录(持续更新中...)
Palindrome Linked List
Given a singly linked list, determine if it is a palindrome.
Example 1:
Input: 1->2
Output: false
Example 2:
Input: 1->2->2->1
Output: true
Follow up:
Could you do it in O(n) time and O(1) space?
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
/*
问题:判断是否为回文链表
方法:用快慢指针法找到链表中部位置,然后翻转右半链表,判断右边链表与左边链表是否相等
O(n),O(1)
*/
class Solution {
public:
bool isPalindrome(ListNode* head)
{
if (!head || !head->next) return true; //异常情况处理,为空结点或者一个结点时
ListNode *slow = head, *fast = head;
while (fast && fast->next) //快慢指针法,让slow指向链表中部位置
{
slow = slow->next;
fast = fast->next->next;
}//退出时,fast为最后一个结点或者null,slow处在中间位置(与结点数有关,左子链表head~slow-1, 右子链表为slow~end,右子链表比左子链表长一或者相等)
//例:0~10,slow 5, fast 10; 0~9,slow5,fast null (0表示头结点,slow和fast的起点)
ListNode* right = reverseList(slow);//反转右边链表
ListNode* left = head;
while(left && right)//比较左右子链表是否相等
{
if(left->val == right->val)
{
left = left->next;
right = right->next;
}
else
return false;
}
return true;
}
//函数:反转链表
ListNode* reverseList(ListNode* head)
{
if(head == nullptr) return nullptr;
ListNode *pre = nullptr, *cur = head,*next; //三个指针分别保存之前,当前,下一个结点
while(cur)
{
next = cur->next; //保存原链表该结点的下一个结点,以免变换指向之后无法遍历到下一个结点
cur->next = pre; //变换指向
pre = cur; //更新指针
cur = next; //更新指针
}
return pre; //最后pre指向最后一个结点,cur指向null
}
};