【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
}
};