這道題目的意思是,在一個數組中尋找兩個數,使這兩個數的和等於給定的數(找到任意一組就可以了)。
題目讀完之後,感覺這道題目還是很簡單的,就是遍歷數組呗,走兩遍,即可以在O(n2)時間復雜度內解決這個問題。不過,仔細想想之後,復雜度還是可以降低的。
首先,我們可以對數組進行排序,這樣,得到的數組就是一個有序數組(假設數組是遞增的),那麼,我們可以利用兩個指針,一個指針指向數組的第一個元素,一個指針指向數組的最後一個元素,所以,就是兩個指針分別指向兩個最值。然後前後每次移動一個指針就可以嘗試的去尋找所需要的一組數。
比如,初始時,兩個指針指向的值相加之後,和大於給定的數字,那麼,就需要把“最大值指針”向前移動,這樣,就會使得兩個指針指向的值的和變小;如果兩個指針指向的值相加小於給定的數字,那麼,就需要把“最小值指針”向後移動,這樣,就會使得兩個指針指向的值的和變大了,然後,終止條件是兩個指針不能相等或者“最小值指針”等於“最大值指針”。
有了上述思想,可以得到如下的解決辦法:
函數聲明:
/*2.12 快速尋找滿足條件的兩個數*/ void DutQuickFindSpecifyTwoNums(int*, int, int, int&, int&);
源代碼:
/*快速尋找兩個值*/
bool _DutQuickFindSpecifyTwoNums = false;
void DutQuickFindSpecifyTwoNums(int* A, int size, int sum, int& one, int& two)
{
if (!A || size <= 1)
{
one = -1;
two = -1;
return;
}
std :: sort(A, A + size);
int i = 0;
int j = size - 1;
/*即前後各一個指針,然後兩個指針往中間方向走,比對遇到的值*/
while (i < j)
{
if (A[i] + A[j] == sum)
{
one = A[i];
two = A[j];
return;
}
else if (A[i] + A[j] > sum)
--j;
else
++i;
}
one = -1;
two = -1;
return;
}