链表类型题目注意事项:
- 需要注意一个节点和空链表的特殊情况。
- 需要考虑链表中特殊位置的存在的处理方式(tail 和head)
- 注意循环中使用next时需要判断该节点本身是否存在,如果不存在则不能使用next。
- 链表类型的题在其他其他数据结构的辅助下进行解题,空间复杂度提高,但是解题会更加的简单。
- 在进行判断类型题操作的时候,最好不要破坏链表的结构。
案例:请编写一个函数,检查链表是否为回文。
给定一个链表ListNode* pHead,请返回一个bool,代表链表是否为回文。
测试样例:
{1,2,3,2,1}
返回:true
{1,2,3,2,3}
返回:false
思路:
回文概念:顺序遍历和反序遍历结构一致。所以最简单的思路可以利用栈的特性,先将所有的节点压入栈中,然后逐个弹出,与节点作比较。
方法一:
# -*- coding:utf-8 -*-
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Palindrome:
def isPalindrome(self, pHead):
# write code here
stack = []
cur = pHead
# 将所有的节点压入栈中
while cur:
stack.append(cur.val)
cur = cur.next
# 出栈并判断是否为回文
while stack:
num = stack.pop()
if num != pHead.val:
return False
pHead = pHead.next
return True空间复杂度为O(n)
方法二:利用快指针和慢指针来减少对额外空间的使用,可将额外的空间缩少致一般,同时利用了回文的对称性。
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Palindrome:
def isPalindrome(self, pHead):
# write code here
# 方法一:O(n)
slow = pHead
fast = pHead.next
stack = []
# 将前半部分的回文压入到栈中
while fast and fast.next:
stack.append(slow.val)
slow = slow.next
fast = fast.next.next
# 注意如果节点为偶数,则慢指针还有一个点没有入栈,需要通过fast指针的状态来判断链表长度为奇数还是偶数。
if fast:
stack.append(slow.val)
slow = slow.next
# 将栈中的数弹出与回文后半部分做比较
while stack:
num = stack.pop()
if num!=slow.val:
return False
slow = slow.next
return True 方法三:不需要借助额外的空间,将后部分的列表进行反序,并返回反序后的头节点,然后与表头进行逐个比较。
# -*- coding:utf-8 -*-
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Palindrome:
def isPalindrome(self, pHead):
# write code here
# 方法一:O(n)
slow = pHead
fast = pHead.next
# 将前半部分的回文压入到栈中
while fast and fast.next:
slow = slow.next
fast = fast.next.next
pre = slow
cur = slow.next
nex = cur.next
# 需要将后半部分进行逆序
while nex: # 判断条件需要考虑
cur.next = pre
pre = cur
cur = nex
nex = nex.next
cur.next = pre
while cur.next != slow:
if cur.val!=pHead.val:
return False
cur= cur.next
pHead = pHead.next
return True

京公网安备 11010502036488号