雙指標,指的是在遍歷物件的過程中,不是普通的使用單個指標進行訪問,而是使用兩個相同方向(快慢指標)或者相反方向(對撞指標)的指標進行掃瞄,從而達到相應的目的。1
在求解相關的問題的過程中,需要兩個指標:快指標和慢指標。兩個指標開始都指向開頭,根據條件不同,快指標走得快,慢指標走的慢,直到滿足條件或者快指標走到結尾。2
要求 : 空間複雜度為o(1)
參考題目:leetcode 142. 環形鍊錶 ii
顯然這個題目可以採用如下方法:
用乙個指標從頭開始遍歷,並將遍歷的值存放在乙個集合中,直到找到第乙個已經存在的元素為止。此時演算法空間複雜度為o(n)。當應用場景需要空間複雜度為o(1)時,單指標顯然無法滿足需求。此時可以借助雙指標進行求解。
畫出雙指標跑動時的示意圖如下。為了便於理解,此處用「距離」代指兩個結點之間需要經過多少個結點,即需要next幾次才能到達。
讓兩個指標同時從起點(頭結點)出發,快指標的速度是慢指標的2倍。兩個指標首次相遇時,兩個指標與起點的距離為 (a+
此時,慢指標尚未走完一圈,走過的距離為 (a+
b)(a+b)
(a+b);
快指標已經走過了n
nn圈,走過的距離為
a +b
+n(b
+c)=
a+(n
+1)b
+nca + b + n(b+c) = a + (n+1)b + nc
a+b+n(
b+c)
=a+(
n+1)
b+nc
同時由於快指標任何時刻走過的距離均為慢指標的2倍,因此快指標的距離也可以寫成
2 (a
+b)2(a+b)
2(a+b)
因此,2(a
+b)=
a+(n
+1)b
+nc⇒
a=(n
−1)b
+nc⇒
a=c+
(n−1
)(b+
c)\begin &2(a+b) &= &a + (n+1)b + nc \\ \rightarrow & a &=& (n-1)b + nc \\ \rightarrow & a & = & c + (n-1)(b+c) \\ \end
⇒⇒2(a
+b)a
a==
=a+
(n+1
)b+n
c(n−
1)b+
ncc+
(n−1
)(b+
c)可以發現,從相遇的位置到入環位置的距離c
cc加上(n−
1)(n-1)
(n−1
)圈的環長(b+
c)(b+c)
(b+c
),恰好等於起點到入環位置的距離。因此,在相遇點和起點各放置乙個每次只走一步的指標,下一次的相遇位置就是入環的位置。
綜上可知,求解題目的思路如下:
定義fas定義參考:tfast
fast
、s lo
wslow
slow
指向頭結點,讓它們一直往下遍歷。其中fas
tfast
fast
的遍歷一次為2個結點,直到兩個結點的值相等;
定義i nl
istinlist
inlist
指標指向頭結點,slo
wslow
slow
和i nl
istinlist
inlist
同時向下開始遍歷,直到兩個結點的值相等;
i nl
istinlist
inlist
(或slow
slow
slow
) 所指的結點即為入環的位置。
↩︎ 文字參考:
↩︎
雙指標演算法
雙指標演算法模板 for int i 0,j 0 i n i 常見問題分類 1 對於乙個序列,用兩個指標維護一段區間 2 對於兩個序列,維護某種次序,比如歸併排序中合併兩個有序序列的操作 例題1 最長連續不重複子序列 給定乙個長度為n的整數序列,請找出最長的不包含重複數字的連續區間,輸出它的長度。輸...
雙指標演算法
title 雙指標演算法 date 2019 05 26 23 45 09 tags 雙指標演算法 雙指標演算法 主要是兩大類 核心思想 將乙個 o n 2 o n 2 o n2 的演算法 優化成 o n o n o n 的for int i 0 i for int j 0 j for i 0,j ...
雙指標演算法
一般雙指標的模板 雙指標演算法的思考方式 先想出暴力做法,再觀察是否存在單調性。傳統的演算法需列舉兩個指標的組合,兩個for迴圈時間複雜度為o n 2 雙指標演算法會使時間複雜度變為o n 給定乙個長度為n的整數序列,請找出最長的不包含重複數字的連續區間,輸出它的長度。輸入格式 第一行包含整數n。第...