链表的题,感觉会了链表的操作应该是没什么问题.链表的访问都是基于while.
1 链表中倒数第k个节点
题目描述
输入一个链表,输出该链表中倒数第k个结点。
解题思路:两种方法,第一种是先访问一便链表,知道链表长度n,然后走到n-k的结点就是.第二个就是先让一个走k步,然后2个一起走,第一个走到头,返回第二个当前所在的结点.由于时间复杂度都一样,就第一种.
class Solution:
def FindKthToTail(self, head, k):
if not head:
return None
n=1
t = head
while(head.next):
head = head.next
n=n+1
if k>n:
return None
i=0
while(i<n-k):
t = t.next
i = i+1
return t
2 反转链表
题目描述
输入一个链表,反转链表后,输出新链表的表头。
解题思路:定义3个变量,pre,cur,nex分别表示上一个节点,当前节点,和下一个节点.pre初始值为None,一共4步:先赋值nex保留下一个节点-->更改cur指针指向pre-->更新pre为当前节点cur-->更新cur为nex. 注意,最好返回的是新的链表的头节点,也就是原来链表的尾结点,具体代码如下:
class Solution:
# 返回ListNode
def ReverseList(self, pHead):
if not pHead:
return None
pre = None
while(pHead):
nex = pHead.next
pHead.next = pre
pre = pHead
pHead = nex
return pre
3 合并2个排序的链表
题目描述
输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。
解题思路:此法有递归和非递归方法,建议2种都要会
1 递归版本
class Solution:
# 返回合并后列表
def Merge(self, pHead1, pHead2):
if not pHead1:
return pHead2
if not pHead2:
return pHead1
if pHead1.val <= pHead2.val:
pHead1.next = self.Merge(pHead1.next, pHead2)
return pHead1
else:
pHead2.next = self.Merge(pHead1, pHead2.next)
return pHead2
2 非递归版本
class Solution:
# 返回合并后列表
def __init__(self):
self.p = None
def Merge(self, pHead1, pHead2):
if not pHead1:
return pHead2
if not pHead2:
return pHead1
if pHead1.val <= pHead2.val:
self.p = pHead1
else:
self.p = pHead2
while(pHead1 and pHead2):
if pHead1.val <= pHead2.val:
temp = pHead1.next
pHead1.next = pHead2
pHead2 = temp
pHead1 = pHead1.next
else:
temp = pHead2.next
pHead2.next = pHead1
pHead1 = temp
pHead2 = pHead2.next
if not pHead1 and pHead2:
pHead1 = pHead2
if not pHead2 and pHead1:
pHead2 = pHead1
return self.p
4 复杂链表的复制
题目描述
输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)
解题思路:不受c的影响,这道题还是很好做的,用递归就解决了.
class Solution:
# 返回 RandomListNode
def Clone(self, pHead):
if not pHead:
return None
temp = RandomListNode(pHead.label)
temp.random = pHead.random
temp.next = self.Clone(pHead.next)
return temp
5 两个链表的第一个公共节点
题目描述
输入两个链表,找出它们的第一个公共结点。
解题思路:如果有公共节点,则两个链表的next指向的是相同的.目前能想到的方法是,分别求为2个链表长度n1和n2,两个长度之差为n2-n1,长的先走n2-n1,短的再走,当他们next相同则是第一个公共节点.
class Solution:
def FindFirstCommonNode(self, pHead1, pHead2):
if not pHead1 or not pHead2:
return None
n1 = 1
n2 = 1
p1 = pHead1
p2 = pHead2
while(pHead1.next):
pHead1 = pHead1.next
n1 = n1+1
while(pHead2.next):
pHead2 = pHead2.next
n2 = n2+1
if pHead1 == pHead2:
i = 0
if n1<=n2:
while(i<n2-n1):
p2 = p2.next
i = i+1
else:
while(i<n1-n2):
p1 = p1.next
i = i+1
while(p1):
if p1 == p2:
return p1
p1 = p1.next
p2 = p2.next
else:
return None
6 链表中环的入口节点
题目描述
给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。
解题思路:先判断是否含有环,有的话一个先走一个后走,两个肯定会碰到一起.如果碰到一起了,一个动一个不动来计算这个环的大小.环大小为N,则一个指针先走N步,然后两个指针一起走,相遇地发就是环的入口.
class Solution:
def EntryNodeOfLoop(self, pHead):
if not pHead:
return None
p1 = pHead
p2 = pHead
fla = False
while(p1.next):
p1 = p1.next
p2 = p2.next.next
if p1 == p2:
fla = True
n = 1
p2 = p2.next
while(p1 != p2):
p2 = p2.next
n = n+1
break
if fla == True:
p11 = pHead
p12 = pHead
for i in range(n):
p11 = p11.next
while(p11 != p12):
p11 = p11.next
p12 = p12.next
return p11
else:
return None
7 删除链表中的重复结点
题目描述
在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5
解题思路:这个题目需要考虑表头重复的情况.