剑指 Offer 24. 反转链表
定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。
示例:
输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL
限制:
0 <= 节点个数 <= 5000
解题思路
cur记录当前节点,pre记录当前节点的前一个节点,翻转之后当前节点cur将指向pre节点。temp记录当前节点的下一个节点。
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution(object):
def reverseList(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
# pre指向当前节点的前一个节点,翻转之后当前节点cur将指向pre节点
pre = None
# 当前节点
cur = head
while cur != None:
# 使用临时指针保存cur的下一个节点
temp = cur.next
# 将当前节点指向前一个节点
cur.next = pre
# pre 和cur都前进一位
pre = cur
cur = temp
return pre
234. 回文链表
请判断一个链表是否为回文链表。
示例 1:
输入: 1->2
输出: false
示例 2:
输入: 1->2->2->1
输出: true
进阶:
你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题?
解题思路
1、先使用快慢指针找到链表的中间节点,slow最终将指向链表的后半部分
如:1 -> 2 -> 3 -> 3 -> 2 -> 1中间节点为第2个3所指向的节点,slow指向第2个3所指向的节点
当长度为奇数时,1 -> 2 -> 3 -> 2 -> 1 的 中间节点为3,slow指向第2个2所指向的节点.
2、对后半部分进行翻转,即将slow指向的链表进行翻转
2、将翻转后的链表与原链表前半部分进行比较,判断是否一致。
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def isPalindrome(self, head: ListNode) -> bool:
# 先使用快慢指针找到链表的中间
slow, fast = head, head
while fast!=None:
slow = slow.next
fast = fast.next
if fast!=None:
fast = fast.next
# slow指在链表的中间处,将链表的后半部分进行翻转
pre = None
while slow!=None:
temp = slow.next
slow.next = pre
pre = slow
slow = temp
# 将原链表的前半部分与翻转后的链表进行比较,如果有不相等的地方,则返回false
# pre指向翻转后的链表
while pre!=None:
if pre.val!=head.val:
return False
pre = pre.next
head = head.next
return True