問題:
1. 快速找出乙個陣列中的兩個數,讓這兩個數之和等於乙個給定的值。
2. 快速找出乙個陣列中的三個數,讓這三個數之和等於乙個給定的值。
1. 解法:演算法複雜度為o(nlogn)。先用快速排序對陣列排序,讓後用雙指標(雙索引)法對排序好的陣列進行反向遍歷,並且遍歷的方向不變。(若是計算兩個數的和,則初始化為i=0,j=n-1,若是計算兩個數的差,則初始化為i=0,j=1)
之所以這樣遍歷方式能成功,是因為排序後,若ai+ajai+aj>sum,則ak+aj>sum(k=i,i+1...j),而i之前j之後的情況已遍歷過,所以只有j--才可能有等號的情況。
[cpp]view plain
copy
#include
#include
using
namespace std;
#define maxn 1001
int a[maxn];
// 總的時間複雜度為o(nlogn)
int main()
else
if (plus < sum)
i++;
else
j--;
} }
2. 解法:時間複雜度為o(n^2)。如果陣列已排序,利用解法1的雙指標遍曆法,可以在o(n)的時間內找到兩個數之和等於乙個給定的數。我們假設找到的三個數ai,aj,ak有ai<=aj<=ak,要讓ai+aj+ak=sum,也就是要ai+aj=sum-ak,設subsum=sum-ak,很容易發現subsum的值只有n個,而確定ai+aj=subsum中的ai,aj只需要o(n)的時間,所以總的時間複雜度為o(nlogn+n*n)=o(n^2)
[cpp]view plain
copy
#include
#include
using
namespace std;
#define maxn 1001
int a[maxn];
int main()
else
if (plus < subsum)
i++;
else
j--;
if (k==i) i++;
if (k==j) j--;
} }
}
若允許每個數被多次選取,只需稍微改下**,具體如下:
[cpp]view plain
copy
#include
#include
using
namespace std;
#define maxn 1001
int a[maxn];
int main()
else
if (plus < subsum)
i++;
else
j--;
//if (k==i) i++;
//if (k==j) j--;
} }
}
快速尋找滿足條件的兩個數
快速尋找滿足條件的兩個數,讓這兩個數字之和等於乙個給定的數字 快速尋找滿足條件的兩個數,讓這兩個數字之和等於乙個給定的數字 public class searchtwonum quicksort.quicksort a 假設sum 9 int sum 9 設定兩個指標 int low 0,high ...
快速尋找滿足條件的兩個數
2012 04 18 16 41 2.12快速尋找滿足條件的兩個數 程式設計師程式設計藝術之五 第一節 尋找滿足條件的兩個數 第14題 陣列 題目 輸入乙個陣列和乙個數字,在陣列中查詢兩個數,使得它們的和正好是輸入的那個數字。要求時間複雜度是o n 如果有多對數字的和等於輸入的數字,輸出任意一對即可...
快速尋找滿足條件的兩個數(程式設計之美)
快速找出乙個陣列中的兩個數,讓此兩個數之和等於乙個給定的數。如 5 6 1 4 7 9 8 中找出兩個數之和等於10的數 程式設計之美之美p177有詳細解答過程,思路是先排序 o nlog n 然後儲存兩個指標beg end,初始指向頭部和尾部,如過 beg end sum,則返回 如果 beg e...