關於Two pointers的個人理解
剛剛在刷題的時候接觸到了一道題,題的大意是給出一個遞增的數字序列,並給出一個m,要求找到a,b兩個數字,且和為m,並且a<b;
在示例中,給出了三種思路,二分、hash值、以及two pointers;
最後一種並沒有接觸過,所以去了解了一下,發現是很值得借鑑的思路;
two pointers思想是對有序陣列的優化遍歷;
如果根據題目中的思想,進行兩層列舉,則不可避免地會使時間複雜度到達O(n^2)級別。但是可以針對序列遞增這一條進行優化;
對這個有序序列,設定兩個索引座標,一個為i,一個為j分別從隊頭和隊尾進行向中間列舉,列舉的邊界條件是i<j;
在列舉過程中,必定會出現三種情況:
在此時注意一個前提條件:i必須保持增加狀態,j必須保持減小狀態;
1.a+b=m,此時是我們想得到的情況,並且該情況發生時,如果i增大,j減小,則a+b可能和不變;
2.a+b>m,此時,在前提條件規範下,我們可以推斷如果b減小,也就是j減小,可以預測會出現a+b=m的情況;
3.a+b<m,此時,在前提條件規範下,我們可以推斷,如果a增大,也就是i增大,可能會出出現a+b=m的情況;
因此,將上述判別寫成程式碼可以有以下結果:
while(i<j){ if(a[i]+a[j]==m){ i++; j--; }else if(a[i]+a[j]<m){ i++; }else{ j--; } }
這種方法可以看成是一種取巧的方法,但是其最大的特點是有效的減少了時間複雜度,在遞增序列的前提下,迴圈只需要進行到i>=j時停止,所以理想狀態下只需要遍歷半個序列,時間複雜度只需要O(n),所以算得上求解的一種好方法;