關於尺取(雙指標)法的理解

2021-09-27 08:43:10 字數 1947 閱讀 7725

以下關於該方法的理解是出自我在寫相關程式的時候遇到的超出所設定時間範圍的問題的乙個解法。該解法在針對某些特定問題的時候可以減少時間成本,即降低時間複雜度。

在某些問題中例如:給定乙個列表a = [a,b,c,d,e,f] ,求出乙個目標值 t,該目標值 t 需要從給定的列表中找出三個數相加得到。三個數只能從列表中找,並且某數的重複次數不得超過列表**現的該數的次數。

有種解決方案是使用迴圈搜尋:

for i in a:

...***

for e in a:

...***

for v in a:

...***

***...

但是這種方法的時間複雜度過高,達到o(n^3),因此最好不要選擇這種解決方案。這個時候可以選擇尺取法。

首先給列表排序。在排序結束之後,固定第乙個值a(其元素假設為 i,一般剛開始它是列表第乙個元素),隨後再固定兩個值,分別是b(假設下標為 left,一般剛開始它是列表第二個元素),與c(假設下標為 right,一般剛開始它是a列表的最後乙個元素)。

然後開始進行計算:

s = a[i] + a[left] + a[right]
計算s與 t 是否相等,如果相等,直接

return s
如果不等,就要判斷s與 t 的關係:

若 s > t,表明我們三個數相加得到的結果大於目標值,此時不用再將 left 往右移動 1 位,即不用再遍歷 left 往後移動的情況。因為列表已經排序,所以即使再往後移動,三數相加結果也必然大於目標值 t 。下面需要做的就是將我們指定的下標為right的數向左移動 1 位,使得三數相加的和降低。然後迴圈,直到找出目標值 t 。在迴圈過程中,一般會出現 left 遍歷一遍之後,仍沒有找到 s = t,那麼下面是將 i 的下標往右移動一位繼續遍歷。

若s < t,與上面的思想一樣,將指定的下標為left的數向右移動 1 位即可,然後迴圈,直到找出 t 。

另外附上python**。這個**是尋找三個數之和中與目標值最接近的,其解決方案和上述思想一致。

(還在學習中,程式寫的著實不好,見諒…)

a 是指定列表,t 是目標值。

class solution(object):

def closestsum(self,a,t):

a.sort()

res =

for i in range(len(a)):

left = i + 1

right = len(a) - 1

if right <= left:

break

for v in range(len(a)):

sum = a[i] + a[left] + a[right]

if sum > t:

right -= 1

if right == left:

break

elif sum < t:

left += 1

if left == right:

break

else:

return sum

abs_res = [abs(t - i) for i in res]

s = min(abs_res)

return res[abs_res.index(s)]

if __name__ == '__main__':

a = solution()

b = a.closestsum([2,4,8,16,32,64,128],82)

print(b)

尺取法(雙指標法)詳解

這節課我們來講尺取法思想。上課!首先,所謂尺取法,是列舉區間的時候的一種優化思想。我們顧名思義地理解,就像是在乙個數軸上,用尺慢慢地取。用比較學術的話來講,就是取一對陣列下標 即區間左右端點 根據題目要求和實際情況不斷地推進左右區間得出答案。你可能會說,這不就是暴力列舉麼?是的,不過它在處理區間的時...

雙指標法的常見應用

標籤 演算法 pivot null面試 2012 08 10 10 09 3247人閱讀收藏 舉報 資料結構 演算法 20 所謂雙指標,指的是在遍歷物件的過程中,不是普通的使用單個指標進行訪問,而是使用兩個相同方向或者相反方向的指標進行掃瞄,從而達到相應的目的。換言之,雙指標法充分使用了陣列有序這一...

11 盛最多水的容器(雙指標法)

container with most water 題目描述 給你 n 個非負整數 a1,a2,an,每個數代表座標中的乙個點 i,ai 在座標內畫 n 條垂直線,垂直線 i 的兩個端點分別為 i,ai 和 i,0 找出其中的兩條線,使得它們與 x 軸共同構成的容器可以容納最多的水。說明 你不能傾斜...