给你一个单链表的头节点
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)
空间复杂度解决此题?
思路:
时间复杂度:O(N)
空间复杂度:O(1)
- /**
- * Definition for singly-linked list.
- * type ListNode struct {
- * Val int
- * Next *ListNode
- * }
- */
- func isPalindrome(head *ListNode) bool {
- if head == nil {
- return true
- }
-
- firstHalfEnd := endOfFirstHalf(head)
- secondHalfStart := reverseList(firstHalfEnd.Next) // 注意传入中点的Next节点
-
- for cur1, cur2 := head, secondHalfStart; cur2 != nil; { // 因为后半部分反转后的尾节点为空(cur2可能会遍历到空节点导致出错),且对于奇数长度的链表,前半部分长度更长(比如:5=3+2)
- if cur1.Val != cur2.Val {
- return false
- }
- cur1 = cur1.Next
- cur2 = cur2.Next
- }
- return true
- }
-
- // 通过快慢指针寻找链表中点,此时slow指向链表的中点
- func endOfFirstHalf(head *ListNode) *ListNode {
- var fast, slow *ListNode = head, head
- for fast.Next != nil && fast.Next.Next != nil { // 注意判断条件
- fast = fast.Next.Next
- slow = slow.Next
- }
-
- return slow
- }
-
- // 反转后半部分链表
- func reverseList(head *ListNode) *ListNode {
- var pre, mid, end *ListNode = nil, head, nil
- for mid != nil {
- end = mid.Next
- mid.Next = pre
- pre = mid
- mid = end
- }
-
- return pre
- }