剛剛在刷題的時候接觸到了一道題,題的大意是給出一個遞增的數字序列,並給出一個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),因此算得上求解的一種好方法;code