今天下雨了,下午在寢室偷懶了乙個小時,部落格總結差點鴿了。今天做了四道鍊錶,兩道簡單兩道中等。稍微感覺找到了一些套路—合理地使用雙指標。明天準備複習總結一下這幾天的知識,不求速度但求掌握,另外還要整理下小**實驗資料,明天鴿了(手動狗頭)。
1、 給乙個鍊錶和乙個數字n,輸出鍊錶的倒數第n個數
2、 刪除鍊錶中重複節點的多餘節點
3、 刪除鍊錶中重複節點
4、尋找鍊錶中環的入口
問題:輸入乙個鍊錶,輸出該鍊錶中倒數第k個結點
簡單分析一下:這道題的思路很直觀,其實就是把鍊錶反序然後輸出第n
nn個節點;不考慮return的要求的話,我們也可以借助佇列的入列操作即可;
不過下面兩種方法掌握起來還是更好一些:
1.加減法:首先遍歷鍊錶得到總長度len
gthlength
length
,輸出倒數第n
nn個,那麼就是正數len
gth+
1−nlength+1-n
length
+1−n
個,即len
gth+
1=n+
poslength+1=n+pos
length
+1=n
+pos
2.雙指標::n
nn可以理解為目標節點與鍊錶尾部之間有n
nn個指標,所以我們可以設定兩個指標,其中乙個放在頭部,另外乙個和它間隔n
nn個指標,然後向後查詢逐步直到後乙個指標指向尾部。
兩種方法都寫一下
另外就是注意細節優化一下,比如k超過鍊錶長度時,k=0時
class
listnode
:def
__init__
(self, x)
: self.val = x
self.
next
=none
#1class
solution1
:def
findkthtotail
(self, head, k)
: cur = head
length =
0while cur:
length = length +
1 cur = cur.
next
if length < k or k ==0:
return
none
else
: target =
none
for i in
range
(length +
1- k)
:while head:
target = head
head = head.
next
return target
#2class
solution
:def
findkthtotail
(self, head, k)
:if head ==
none
:return
none
else
: fast,slow = head,head
for i in
range
(k):
ifnot fast:
return
none
fast=fast.
next
while fast!=
none
: slow = slow.
next
fast = fast.
next
return slow
我們先看一下兩道問題,細品下
其實不同之處就是在於保留不保留重複的節點,兩個問題都可以用雙指標解決。設定兩個指標pre
,cur
pre,cur
pre,cu
r在遍歷一次鍊錶的過程中,要做的就是比較前後兩個節點,如果值相等固定pre
prepr
e,cu
rcur
cur往後移乙個;否則,兩個指標都往後移動一步。
class
listnode
:def
__init__
(self, val)
: self.val = val
self.
next
=none
class
solution
:def
deleteduplicates
(self , head )
:if head==
none
or head.
next
==none
:return
none
else
: pre,cur = head,head
while pre and cur:
if pre.val==cur.vall:
pre.
next
= cur.
next
else
: pre = pre.
next
cur = cur.
next
return head
class
solution1
:def
deleteduplicates
(self , head )
: trick=listnode(0)
#這是乙個處理頭部節點重複時的技巧
trick.
next
= head
cur = trick
while cur.
next
and cur.
next
.next
: p1,p2 = cur.
next
and cur.
next
.next
if p1.val!=p2.val:
cur = cur.
next
else
:while p2 and p1.val==p2.val:
p2 = p2.
next
cur.
next
= p2
return trick.
next
雙指標,雙指標,雙指標
我們先看一張圖
判斷鍊錶中是否有環的快慢指標方法,說的實際一點就是操場跑圈,跑的快的會在環的某處追上慢的。看一下上面的圖:最初快慢指標都在x處,快指標跑兩步,慢指標跑一步,經過一段時間後,兩者第一次在z又遇見了,這時候我們讓快指標從z點之後都跑一步,讓慢指標從x從頭跑,兩者下一次就會在環入口點遇見。
推導一下:第一次在z點遇見時,很顯然快指標走的路程是慢指標的兩倍,可以列式子:2*(a+b)=a+(b+c)*n+b,推出a=(n-1)b+nc=(n-1)(b+c)+c; 接下來,慢指標跑了a到達y,慢指標跑了c到達y,相遇。
class
solution
:def
detectcycle
(self , head )
:# write code here
fast = head
slow = head
while fast:
if fast.
next
: fast = fast.
next
.next
slow = slow.
next
if fast == slow:
break
else
:return
none
ifnot fast:
return
none
fast = head
while fast != slow:
fast = fast.
next
slow = slow.
next
return fast
堅持堅 OI刷題記錄
2014 4 18 poj3264 bzoj1699 balanced lineup rmq 2014 4 19 bzoj1012 jsoi2008 最大數maxnumber noi2004 鬱悶的出納員 bzoj3224 tyvj 1728 普通平衡樹 2014 4 20 bzoj1862 105...
面試刷題記錄
寫一段 判斷乙個包括 的表示式是否合法 注意看樣例的合法規則。給定乙個表示式a,請返回乙個bool值,代表它是否合法。測試樣例 a b 5 4 返回 true 測試樣例 a b 5 4 返回 false include vector include iostream using namespace ...
刷題記錄 2015 11 14
現在每天做的題都記錄一下,免得不知道自己在幹什麼。poj2406 用next陣列的定義求迴圈節 poj3261 字尾陣列 題 spoj705 同上,這題我wa了幾次,結果發現 我以為字串只有大寫字母,其實有小寫。如下 poj2406 author duyixian date 2015 11 14 1...