1. 程式人生 > 其它 >尺取演算法

尺取演算法

技術標籤: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- -)

③ a[ i ] + a[ j ] < sum (i++)

#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; }

在這裡插入圖片描述