请判断一个链表是否为回文链表。
示例 1:
输入: 1->2 输出: false
示例 2:
输入: 1->2->2->1 输出: true
进阶:
你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题?
思路一:用数组,时间复杂度O(n),空间复杂度O(n)
/** * Definition for singly-linked list. * public class ListNode { * public var val: Int * public var next: ListNode? * public init(_ val: Int) { * self.val = val * self.next = nil * } * } */ class Solution { func isPalindrome(_ head: ListNode?) -> Bool { if head == nil || head?.next == nil { return true } var head = head var stack:[Int] = [(head?.val)!] while head?.next != nil { stack.append((head?.next!.val)!) head = head?.next } return stack == stack.reversed() } }
思路二:快慢指针找中间结点,同时将前半部分反转,然后与剩下的后半部分做比较,时间复杂度O(n),空间复杂度O(1)
/** * Definition for singly-linked list. * public class ListNode { * public var val: Int * public var next: ListNode? * public init(_ val: Int) { * self.val = val * self.next = nil * } * } */ class Solution { func isPalindrome(_ head: ListNode?) -> Bool { if head == nil || head?.next == nil { return true } //快慢指针寻找中间节点,同时把前半部分反转 var slow = head, fast = head var pre: ListNode? = nil //若12321,运行完 slow = 321,fast = 1,中间结点为3,pre = 21 //若1221,运行完 slow = 21,fast = nil,中间结点为第2个2,pre = 21 while fast != nil && fast?.next != nil { let cur = slow slow = slow?.next fast = fast?.next?.next //下面是同时反转前半部分 cur?.next = pre pre = cur } //链表奇数个时,后半部分略过中间结点 if fast != nil { slow = slow?.next } //slow后半部分的值和pre反转后的前半部分的值做比较 while slow != nil && pre != nil { if slow?.val != pre?.val { return false } slow = slow?.next pre = pre?.next } return true } }