链表中换的入口节点
# -*- coding:utf-8 -*-
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def EntryNodeOfLoop(self, pHead):
# write code here
# 推荐解法,双指针方法(新学习到的思路)两个指针,初始时都在链表开头,然后快指针每次移两格
# 慢指针每次移一格,如果有环,那么快慢指针一定会在环中某位置相遇,且快指针至少超慢指针一圈
# 设相遇时快指针走过s,慢指针走过f,那么s=2f
# 因为快指针至少超慢指针一圈,设环周长为c,那么s=f+?c
# 解得f=?c,再设链表除了环以外的长度为a,那么慢指针要走到环入口处需要在现在基础上再加a
# 因此在此时将快指针重新置为链表开头,并且与慢指针一起每次走一格,因为这样可以保证快慢指针
# 同时走了a步,并且在环入口相遇
if not pHead:
return None
k, m = pHead, pHead
while k and k.next:
k = k.next.next
m = m.next
if k == m:
break
if not k or not k.next:
return None
k = pHead
while k != m:
k = k.next
m = m.next
return m
# 思想简单的解法,但时间空间复杂度高
# 建立空集合,遍历链表,每走一步都保存现在的节点在集合中,直到找到重复的节点
head_set = {}
while pHead:
if pHead not in head_set.keys():
head_set[pHead] = 1
pHead = pHead.next
else:
return pHead
链表中倒数k个节点
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
#
# @param pHead ListNode类
# @param k int整型
# @return ListNode类
#
class Solution:
def FindKthToTail(self , pHead: ListNode, k: int) -> ListNode:
# write code here
# 使用数组保存链表,直接使用数组取倒数第k个
res = []
while pHead:
res.append(pHead)
pHead = pHead.next
if k>len(res) or k == 0:
return None
return res[-k]
# 使用栈,用法与数组类似
stack = []
num = 0
while pHead:
stack.append(pHead)
pHead = pHead.next
num += 1
if num<k or k == 0:
return None
else:
while k>1:
stack.pop()
k -= 1
return stack.pop()
# 双指针方法,定义头尾指针,差距为k,然后同时移动头尾指针依次往后走一格,知道尾指针的next为空时停止,返回头指针
if k == 0:
return None
tou = pHead
for i in range(k-1):
if not pHead:
return None
else:
pHead = pHead.next
if not pHead:
return None
while pHead.next:
tou = tou.next
pHead = pHead.next
return tou
# 最简单的方法,首先遍历完整个链表获取长度,然后长度小于k返回空,否则继续遍历长度-k
len_head = 0
temp = pHead
while temp:
temp = temp.next
len_head += 1
if len_head<k:
return None
else:
num = len_head - k
for i in range(num):
pHead = pHead.next
return pHead