《剑指offer》 Day4
反转链表
题目:定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。
该题的图文解析可以看为的博客 反转链表
# 定义一个节点
class listNode():
def __init__(self, elem=None):
self.elem = elem
self.next = None
# 反转链表
def reverse_list(p_head):
# 定义一个空节点,用于存储反转后的头节点
reverse_head = listNode()
# 存储当前链表的头节点
cur = head
# 定义一个空节点,用于存储反转过程中断开的节点
prev = listNode()
# 判读当前指针是否为空,空的话就结束循环
while cur:
# 存储下一个节点
p_next = cur.next
# 如果节点不为空,则把该节点设为反转后的头节点
if p_next != None:
reverse_head = p_next
# 把当前节点指向过去的那个节点
cur.next = prev
# 再把当前节点设置为过去的节点
prev = cur
# 当前节点向前移动
cur = p_next
return reverse_head
链表中环的入口节点
题目:如果一个链表中包含环,如何找出环的入口节点?
先判断一个链表中是不是有环,然后通过相遇的节点,可以计算出来环中有n个节点,再定义两个指针p1、p2,其中一个指针p1先移动n步,然后p1和p2同时移动,两个指针相遇的地方就是环的入口
class listNode():
def __init__(self, elem=None):
self.elem = elem
self.next = None
# 判读是不是换,并返回相遇的节点
def meeting_node(p_head):
if not p_head:
return None
slow = p_head
fast = p_head
while fast.next:
fast = fast.next
if fast == slow:
return fast
if fast.next == None:
return None
fast = fast.next
slow = slow.next
return None
# 换的入口
def entry_node_of_loop(p_head):
# 判断是不是有环
m_node = meeting_node(p_head)
if not m_node:
return False
# 计算环中节点的个数
p_cnt = p_head
cnt = 0
round_length = 0
while p_cnt.next:
if p_cnt == m_node:
cnt += 1
if cnt == 1:
round_length += 1
if cnt == 2:
break
p_cnt = p_cnt.next
# 寻找环的入口
slow = p_head
fast = p_head
while round_length:
fast = fast.next
round_length -= 1
while slow != fast:
slow = slow.next
fast = fast.next
return slow
链表中倒数第k个节点
题目:输入一个链表,输出该链表中倒数第k个节点。
第一种:可以先把链表遍历,计算链表的长度,然后减去k以后,在重头开始遍历,就可以得到倒数第k个
第二种:定义两个指针p1、p2,p1指针先走 k步,然后p2和p1再一起向前走,这样p1走到链表尾部以后,p2刚好是倒数第k个
def find_kth_to_tail(p_head, k):
p_ahead = p_head
p_behind = p_head
for i in range(k):
p_ahead = p_ahead.next
while p_ahead:
p_ahead = p_ahead.next
p_behind = p_behind.next
return p_behind
欢迎大家关注我的个人公众号,同样的也是和该博客账号一样,专注分享技术问题,我们一起学习进步