给你一个单链表的头节点
head
,请你判断该链表是否为回文链表。如果是,返回true
;否则,返回false
。示例 1:
编辑
输入:head = [1,2,2,1]
输出:true
示例 2:
编辑
输入:head = [1,2]
输出:false
提示:
- 链表中节点数目在范围
[1, 105]
内0 <= Node.val <= 9
进阶:你能否用
O(n)
时间复杂度和O(1)
空间复杂度解决此题?
思路:
- 找到前半部分链表的尾节点
- 反转后半部分链表
- 判断是否回文
恢复链表并返回结果- 注意 isPalindrome() 中的判断条件:cur2 != nil; 因为后半部分链表在反转后的尾节点为空(cur2可能会遍历到空节点导致出错);且对于奇数长度的链表,前半部分长度更长(比如:5=3+2),所以只判断后半部分的cur2不为空即可~
时间复杂度:O(N)
空间复杂度:O(1)
/*** Definition for singly-linked list.* type ListNode struct {* Val int* Next *ListNode* }*/funcisPalindrome(head*ListNode) bool { ifhead==nil { returntrue } firstHalfEnd :=endOfFirstHalf(head) secondHalfStart :=reverseList(firstHalfEnd.Next) // 注意传入中点的Next节点forcur1, cur2 :=head, secondHalfStart; cur2!=nil; { // 因为后半部分反转后的尾节点为空(cur2可能会遍历到空节点导致出错),且对于奇数长度的链表,前半部分长度更长(比如:5=3+2)ifcur1.Val!=cur2.Val { returnfalse } cur1=cur1.Nextcur2=cur2.Next } returntrue} // 通过快慢指针寻找链表中点,此时slow指向链表的中点funcendOfFirstHalf(head*ListNode) *ListNode { varfast, slow*ListNode=head, headforfast.Next!=nil&&fast.Next.Next!=nil { // 注意判断条件fast=fast.Next.Nextslow=slow.Next } returnslow} // 反转后半部分链表funcreverseList(head*ListNode) *ListNode { varpre, mid, end*ListNode=nil, head, nilformid!=nil { end=mid.Nextmid.Next=prepre=midmid=end } returnpre}