(一)反转链表
暴力解法:
def ReverseList(self , head: ListNode) -> ListNode:
# write code here
if head == None:
return None
v=[]
while head:
v.append(head)
head=head.next
r_v=v[::-1]
phead=r_v[0]
cur=phead
for x in r_v[1::]:
cur.next=x
cur=cur.next
cur.next=None
return phead
遍历链表,然后在列表里反转。计算复杂度:o(n),空间复杂度:o(n)
最优解:
def ReverseList(self , head: ListNode) -> ListNode:
# write code here
if not head:
return None
pre=None
while head:
tmp=head.next
head.next=pre
pre=head
head=tmp
return pre
计算复杂度:o(n),空间复杂度:o(1)
(二)链表中环的入口结点
双指针解法:
def EntryNodeOfLoop(self, pHead):
# write code here
if not pHead:
return None
p1,p2=pHead,pHead
while p1 and p2:
p1=p1.next
if not p1:
return None
p1=p1.next
p2=p2.next
if p1==p2:
p1=pHead
while p1!=p2:
p1=p1.next
p2=p2.next
return p1
快指针每次走两步,慢指针每次走一步。两指针第一次相遇时相差n个环的长度。再将快指针重置在起点,每次只走一步,而慢指针的位置和速度则保持不变,两者再次相遇时,即为环的结点。
计算复杂度:o(n)
空间复杂度:o(1)
(三)链表中倒数最后k个结点
双指针解法
def FindKthToTail(self , pHead: ListNode, k: int) -> ListNode:
# write code here
if not pHead:
return None
p1,p2=pHead,pHead
i=0
while p1 and i<k:
i+=1
p1=p1.next
if i<k and not p1:
return None
while p1 and p2:
p1=p1.next
p2=p2.next
return p2
计算复杂度:o(n)
空间复杂度:o(1)
(四)复杂链表的复制
哈希表的解法,计算复杂度:o(n),空间复杂度;o(n)
def Clone(self, pHead):
# write code here
if not pHead:
return None
dct=dict()
cur=pHead
while cur:
dct[cur]=RandomListNode(cur.label)
cur=cur.next
cur=pHead
while cur:
dct[cur].next=dct.get(cur.next)
dct[cur].random=dct.get(cur.random)
cur=cur.next
return dct[pHead]
递归的解法,计算复杂度:o(n),空间复杂度;o(1)
def Clone(self, pHead):
# write code here
if not pHead:
return pHead
p = RandomListNode(pHead.label)
p.random = pHead.random
p.next = self.Clone(pHead.next)
return p
(五)删除链表中重复的结点
暴力解法:遍历链表,列表存储(不做介绍)
边遍历边构造结果,计算复杂度:o(n),空间复杂度:o(1)
def deleteDuplication(self , pHead: ListNode) -> ListNode:
# write code here
dummy = ListNode(-1)
tail = dummy
while pHead != None:
if not pHead.next or pHead.next.val != pHead.val:
tail.next = pHead
tail = pHead
while pHead.next and pHead.val == pHead.next.val:
pHead = pHead.next
pHead = pHead.next
tail.next =None
return dummy.next
双指针的解法,引入flags判断指针是否处在重复节点边缘。 计算复杂度:o(n),空间复杂度:o(1)
def deleteDuplication(self , pHead: ListNode) -> ListNode:
# write code here
if not pHead:
return None
p1=pHead
p2=pHead.next
dummy=ListNode(-1)
tail=dummy
flags=True
while p1 and p2:
if p1.val!=p2.val and flags:
tail.next=p1
tail=tail.next
if p1.val==p2.val:
flags=False
if p1.val!=p2.val and not flags:
flags=True
p1=p1.next
p2=p2.next
if not flags:
tail.next=None
return dummy.next
else:
tail.next=p1
return dummy.next