尺取演算法
阿新 • • 發佈:2021-01-20
技術標籤:zero
尺取法
尺取法可以用來優化for迴圈,降低程式的時間複雜度。
例題:第一行是一個整數n,表示陣列元素的個數。第二行有n個空格分隔的整數。第三行有一個整數sum。輸出一個整數,表示有多少對元素之和等於sum。
輸入格式:
6
1 3 5 7 9 31
10
輸出:
2
尺取的思想:對於一個遞增的序列,定義兩個指標i,j遍歷陣列選取兩數求和,i從左往右遍歷,j從右往左遍歷,會出現三種情況。sum以10為例
① a[ i ] + a[ j ] == sum
此時直接記錄下此情況,然後執行i++和j- -操作來尋找下一種兩數之和等於10可能的情況(i++會使a[ i ]變大,j- -會使a[ j ]變小,整體和不變)。
② a[ i ] + a[ j ] > sum
a[ i ] + a[ j ] > 10的原因是第二個數過大,此時若想使兩數之和等於10,需要對 j 指標進行 j- -操作。操作完成之後a[ j ] = 9,如此遍歷陣列,尋找兩數和為10的情況。
③ a[ i ] + a[ j ] < sum
a[ i ] + a[ j ] < 10的原因是a[ i ]過小,此時可執行 i++使a[ i ]變大,即a[ i ] = 3 從而使 a[ i ] + a[ j ] = 10。
綜上:若
① a[ i ] + a[ j ] == sum (i++ j- -)
② a[ i ] + a[ j ] > sum (j- -)
#include <cstdio>
#include <iostream>
using namespace std;
int a[10010];
int main()
{
int n;
cin >> n;
for (int i = 1;i <= n;i++) cin >> a[i];
int sum;
cin >> sum;
//定義雙指標
int i = 1,j = n;
int ans = 0;
//核心程式碼
while (i < j)
{
if (a[i] + a[j] == sum)
{
ans += 1;
i++;
j--;
}
else if (a[i] + a[j] > sum) j--;
else if (a[i] + a[j] < sum) i++;
}
cout << ans << endl;
return 0;
}