目錄
鏈表
1、從尾到頭打印鏈表
問題:輸入一個鏈表,按鏈表值從尾到頭的順序返回一個ArrayList。
思路:直接遍歷一遍鏈表保存結果到list中,再返回倒序的list即可。
# -*- coding:utf-8 -*-
class ListNode:
def __init__(self, x):
self.val = x
self.next = None
class Solution:
# 返回從尾部到頭部的列表值序列,例如[1,2,3]
def printListFromTailToHead(self, listNode):
# write code here
arr=[]
while listNode:
arr.append(listNode.val)
listNode=listNode.next
return arr[::-1]
2、鏈表中倒數第K個結點
問題:輸入一個鏈表,輸出該鏈表中倒數第K個結點。
思路:先計算鏈表的長度,然後計算找到倒數第k個需要幾次循環,並判其中關係。最後,用for循環,不斷將指針指向下一個節點,即爲所求。
# -*- coding:utf-8 -*-
class ListNode:
def __init__(self, x):
self.val =x
self.next =None
class Solution:
def FindKthToTail(self,head,k):
len_node=0
temp=head
while temp:
temp=temp.next
len_node+=1
run_times=len_node-k
if run_times<0 or k<0:
return
for i in range(run_times):
head=head.next
return head
3、反轉鏈表
問題:輸入一個鏈表,反轉鏈表後,輸出鏈表的所有元素。
思路:利用三個指針逐個翻轉(頭插法建立單鏈表)。
# -*- coding:utf-8 -*-
class ListNode:
def __init__(self, x):
self.val =x
self.next =None
class Solution:
def ReverseList(self,phead):
if not phead:
return
p=phead
q=phead.next
p.next=None
while q:
r=q.next
q.next=p
p=q
q=r
return p
4、合併兩個排序的鏈表
問題:輸入兩個單調遞增的鏈表,輸出兩個鏈表合成後的鏈表,需要合成後的鏈表滿足單調不減規則。
思路一:迭代方法求解。
# -*- coding:utf-8 -*-
class ListNode:
def __init__(self, x):
self.val =x
self.next =None
class Solution:
def Merge(self,pHead1,pHead2):
p1=pHead1
p2=pHead2
if p1 and p2: #首先,判斷哪個鏈表的頭結點的值小,將值小的作爲合併後鏈表的頭結點
if p1.val<=p2.val:
head=p1
p1=p1.next
else:
head=p2
p2=p2.next
r = head
elif p1:
return p1
else:
return p2
while p1 and p2:
if p1.val<=p2.val:
r.next=p1
p1=p1.next
r=r.next
else:
r.next=p2
p2=p2.next
r=r.next
if p1:
r.next=p1
if p2:
r.next=p2
return head
思路二:遞歸方法。
# -*- coding:utf-8 -*-
class ListNode:
def __init__(self, x):
self.val =x
self.next =None
class Solution:
def Merge(self,pHead1,pHead2):
merged=None
if not pHead1: #當pHead1爲空時,返回pHead2
return pHead2
if not pHead2: #當pHead2爲空時,返回pHead1
return pHead1
#第一個鏈表中的第一個點小於第二個鏈表中的第二個點,那麼merged第一個點就是pHead1的第一個點
#對於它的next,繼續執行遞歸
if pHead1.val<=pHead2.val:
merged=pHead1
pHead1=pHead1.next
merged.next=self.Merge(pHead1,pHead2)
else:
merged=pHead2
pHead2=pHead2.next
merged.next=self.Merge(pHead1,pHead2)
return merged
5、複雜鏈表的複製
問題:輸入一個複雜鏈表(每個節點中有節點值,以及兩個指針,一個指向下一個節點,另一個特殊指針指向任意一個節點),返回結果爲複製後複雜鏈表的head。(注意,輸出結果中請不要返回參數中的節點引用,否則判題程序會直接返回空)
# -*- coding:utf-8 -*-
class RandomListNode:
def __init__(self, x):
self.label =x
self.next =None
self.random=None
class Solution:
def Clone(self,pHead):
if not pHead:
return pHead
#開闢一個新結點
copy=RandomListNode(pHead.label)
copy.next=pHead.next
copy.random=pHead.random
#遞歸剩餘的結點
copy.next=self.Clone(pHead.next)
return copy
6、兩個鏈表的第一個公共結點
問題:輸入兩個鏈表,找出它們的第一個公共結點。
# -*- coding:utf-8 -*-
class ListNode:
def __init__(self,x):
self.val=x
self.next=None
class Solution:
def FindFirstCommonNode(self,pHead1,pHead2):
if not pHead1 or not pHead2:
return None
length1=0
length2=0
p1=pHead1
p2=pHead2
#分別計算兩個鏈表的長度
while p1:
length1+=1
p1=p1.next
while p2:
length2+=1
p2=p2.next
#根據兩個鏈表的長度,確定長、短鏈表和它們之間的長度差
if length1>=length2:
step=length1-length2
longList=pHead1
shortList=pHead2
else:
step=length2-length1
longList=pHead2
shortList=pHead1
#讓長鏈表先走step步
for i in range(step):
longList=longList.next
#同時遍歷兩個鏈表,讓他們不斷指向next,並判斷何時相等,相等時返回任一一個鏈表即可
while longList and shortList:
if longList==shortList:
return longList
else:
longList=longList.next
shortList=shortList.next
return None
7、鏈表中環的入口點
問題:一個鏈表中包含環,請找出該鏈表的環的入口點。
思路:第一步,找環中相匯點。分別用p,q指向鏈表頭部,p每次走兩步,q每次走一步,直到p==q找到在環中的相匯點。
第二步,找環的入口。接上一步,當p==q時,p所經過的節點數爲2x,q所經過的節點數爲x,設環中有n個節點,p比q多走一個環,有2x=x+n;n=x;可以看出q實際走了一個環的步數,再讓p指向鏈表頭部,q位置不變,p,q每次走一步直到p==q;此時p,q指向環的入口。
# -*- coding:utf-8 -*-
class ListNode:
def __init__(self,x):
self.val=x
self.next=None
class Solution:
def EntryNodeOfLoop(self,pHead):
if pHead==None:
return None
if pHead.next==None or pHead.next.next==None:
return None
#使用快慢指針,p每次走兩步,q每次走一步
p=pHead.next.next
q=pHead.next
#第一次循環,直到p和q相遇,p每次走兩步,q每次走一步
while p!=q:
p=p.next.next
q=q.next
if p.next==None or p.next.next==None:
return None
#第二次循環,直到p和q相遇,讓快指針p回到開始的點,p和q每次都走一步
p=pHead
while p!=q:
p=p.next
q=q.next
return p
8、刪除鏈表中重複的結點
問題:在一個排序的鏈表中,存在重複的結點,請刪除該鏈表中重複的結點,重複的結點不保留,返回鏈表頭指針。例如,鏈表1->2->3->3->4->4->5處理後爲1->2->5。
# -*- coding:utf-8 -*-
class ListNode:
def __init__(self,x):
self.val=x
self.next=None
class Solution:
def deleteDuplication(self,pHead):
temp=[]
head=pHead
#先將pHead中所有結點的value全部放到temp列表中去
while head:
temp.append(head.val)
head=head.next
result=ListNode(0) #創建一個新的指針
head=result #讓head指向這個指針
for i in temp:
if temp.count(i)==1: #對於temp中的元素,如果出現次數等於1就添加到head的next指針
head.next=ListNode(i)
head=head.next
return result.next