two pointers思想(序列合併問題)

2021-10-06 01:43:20 字數 1209 閱讀 2101

給定乙個遞增的正整數序列和乙個正整數m,求序列中的兩個不同位置的數a和b,使得它們的和恰好為m,輸出所有滿足條件的方案。

如果直接兩重迴圈會使複雜度過高,two pointers思想利用序列遞增性質,來降低複雜度。如果a[i]+a[j] > m,那麼a[i]+a[j+1]一定 >m,同時a[i+1]+a[j]也一定 >m。具體針對本題的演算法如下:

令下標i的初值為0,下標j的初值為n-1,指向序列的第乙個和最後乙個元素,接下來根據a[i]+a[j]的大小進行下面三種選擇,令i不斷++,j不斷–,直到i>=j成立。

如果滿足a[i]+a[j] == m,說明找到了其中一組方案。由於序列遞增,不等式a[i+1]+a[j] >m ,與a[i]+a[j-1] 如果滿足a[i]+a[j] > m,由於序列遞增,不等式a[i+1]+a[j]一定》m,因此剩餘答案只可能在[i,j-1]中區間內產生,令j=j-1。

如果滿足a[i]+a[j] < m,由於序列遞增,不等式a[i]+a[j-1]一定

反覆執行上面三個判斷,直到i>=j成立。

while

(ielse

if(a[i]

+a[j]

< m)

else

}

假設有兩個遞增序列a和b,要求將它們合併為乙個遞增序列c。

同樣設定兩個下標i,j,初值均為0,表示分別指向序列a的第乙個元素和序列b的第乙個元素,然後根據a[i]和b[j]的大小來決定哪乙個放入序列c。

如果a[i] 如果a[i] >b[j],說明b[j]是當前序列a與序列b中剩餘元素中最小的乙個,因此把b[j]加入序列c,並讓j++。

如果a[i] ==b[j],則選擇任意乙個加入序列c中,並讓對應的下標加1。

上面的分支操作直到i、j中的乙個到達序列末端為止,然後將另乙個序列的所有元素依次加入序列c中。

int

merge

(int a,

int b,

int c,

int n,

int m)

else

}while

(i]= a[i++];

while

(j]= b[j++];

return index;

//返回序列c的長度

}

two pointers思想就是利用序列本身的特性,使用兩個下標i、j對序列進行掃瞄,以較低的複雜度解決問題。

演算法思維 two pointers

easy 級例題 給定乙個遞增的具有n個元素的正整數序列arr和乙個正整數s,求序列中兩個不同位置的數a和b,使他們的和恰好等於s,輸出所有滿足條件的結果i和j。如序列arr 和正整數s 9,就有 4 5 和 3 6 本例最簡單的方法就是利用二重迴圈列舉所有的可能性,得出結果。但是這樣做的時間複雜度...

演算法筆記 two pointers

從乙個題目引入 給定乙個序列和正整數m 8,求序列中的兩個數 a b m本題最直接的解法就是列舉 for int i 0 i n i 顯然,這個解法的時間複雜度為o n 當n為 10 5 的規模是不可承受的 利用序列的遞增特性,我們可以利用以下解法 反覆執行直到i j成立 while i j els...

Two pointers技巧的應用

查詢陣列中兩個位置不同的數字之和為sum的個數。先來看看暴力法,粗略估計,時間複雜度為0 n 2 void violence int a,int totalnumber,int sum int count 0 計算不匹配的結果次數 不匹配次數是41次,嗯,看起來結果還不錯的樣子。來看看two poi...