給定乙個遞增的正整數序列和乙個正整數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...