1. 题目
请判断一个链表是否为回文链表。
2. 示例
示例 1:
输入: 1->2 输出: false
示例 2:
输入: 1->2->2->1 输出: true
3. 解答
python3
将链表的每个结点记录在数组中,在进行数值判别。时间复杂度为O(n),空间复杂度为O(n)。
class Solution(object): def isPalindrome(self, head): """ :type head: ListNode :rtype: bool """ listnode = [] while head: listnode.append(head) head = head.next for i in range(int(len(listnode)/2)): if listnode[i].val != listnode[len(listnode)-i-1].val: return False return True solution = Solution() head = ListNode(0) # cur = head # for i in range(1, 5): # node = ListNode(i) # cur.next = node # cur = node n1 = ListNode(1) head.next = n1 n2 = ListNode(2) n1.next = n2 n3 = ListNode(2) n2.next = n3 n4 = ListNode(1) n3.next = n4 n5 = ListNode(0) n4.next = n5 print(head) s = solution.isPalindrome(head) print(s)
4. 优答
进阶:
你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题?
算法思想:
(1)找到中间结点
(2)将后面半部分的结点进行反转(也可用使用栈的后进先出的特性,但是空间复杂度就是O(n/2))
(3)比较前面半部分和后面半部分结点的大小
技巧:
(1)单链表找中点:使用快慢指针同步计数,每次快指针走两步,慢指针走一步,当快指针走完时,慢指针刚好走了一半,正好索引到链表的中点。
(2)链表逆序可以参看之前的题:单链表逆序。
class Solution(object): def reverseList(self, head): if head == None: return head pre = head cur = head.next while cur != None: pre.next = cur.next cur.next = head head = cur cur = pre.next return head def isPalindrome(self, head): if head is None or head.next is None: return True fast = slow = head while fast and fast.next: slow = slow.next fast = fast.next.next # slow = self.reverseList(slow) ##### 这里面要考虑奇偶数的问题。 # 如果是奇数个结点,那么fast是指向最后一个元素,它的next为None。 # 如果是偶数个结点,那么fast是None。 if fast: # 奇数个结点,slow指向的是中间那个结点,要逆序的是中间结点后面的链表 slow.next = self.reverseList(slow.next) slow = slow.next else: # 偶数个结点,slow指向的是后面要逆序链表的头结点 slow = self.reverseList(slow) while slow: if head.val != slow.val: return False head = head.next slow = slow.next return True solution = Solution() head = ListNode(0) # cur = head # for i in range(1, 5): # node = ListNode(i) # cur.next = node # cur = node n1 = ListNode(1) head.next = n1 n2 = ListNode(2) n1.next = n2 n3 = ListNode(2) n2.next = n3 n4 = ListNode(1) n3.next = n4 n5 = ListNode(0) n4.next = n5 print(head) s = solution.isPalindrome(head) print(s)
另一种解答:
class Solution: def isPalindrome(self, head): reverse, fast = None, head # Reverse the first half part of the list. while fast and fast.next: fast = fast.next.next head.next, reverse, head = reverse, head, head.next # If the number of the nodes is odd, # set the head of the tail list to the next of the median node. tail = head.next if fast else head # Compare the reversed first half list with the second half list. # And restore the reversed first half list. is_palindrome = True while reverse: is_palindrome = is_palindrome and reverse.val == tail.val reverse.next, head, reverse = head, reverse, reverse.next tail = tail.next return is_palindrome