Coding:在数组中查找具有给定总和的对
原创
©著作权归作者所有:来自51CTO博客作者luoyayun361的原创作品,请联系作者获取转载授权,否则将追究法律责任
PS:没事儿做做题,预防老年痴呆~
描述
给定一个未排序的整数数组,找到其中有给定总和的一对数字。
eg:
输入:
arr = [3,5,2,9,7,6,11,0]
sum = 10
输出:
索引 0和4
只要找到一对数字即可。
方法一
最简单也是最暴力的方法,用两个循环遍历数组,判断两个数字之和,如果符合条件则返回数组下标。该方法比较简单,但是时间复杂度为O(n^2),比较高。
直接上代码,C++实现
// 时间复杂度O(n^2) 空间复杂度 O(1)
vector<int> findPair1(const vector<int> &arr,int sum)
{
for(int i = 0 ; i < arr.size()-1 ; ++i){
for(int j = i + 1 ; j < arr.size() ; ++j){
if(arr[i] + arr[j] == sum){
return {i,j};
}
}
}
return {};
}
int main()
{
vector<int> arr = {3,5,2,9,7,6,11,0};
int sum = 10;
auto ret = findPair1(arr,sum);
if(0 == ret.size()){
cout << "pair not found." << endl;
}
for(auto &iter : ret){
cout << iter << " ";
}
return 0;
}
方法二
第二种方法借用排序来实现,首先对数据进行排序,然后定义两个索引变量分别指向数组的头和尾,将索引头和尾的元素总和与期望值进行比较,如果小于期望值,则把低位索引加1,如果大于期望值,则把高位索引减1,通过循环直到低索引比高索引大,则返回。该方法时间复杂度为O(n*logn)。
上代码
// 时间复杂度O(nlogn) 空间复杂度 O(1)
vector<int> findPair2(vector<int> &arr,int sum)
{
std::sort(arr.begin(),arr.end());
int low = 0;
int high = arr.size() - 1;
while(low < high){
if(arr[low] + arr[high] == sum){
return {low,high};
}
(arr[low] + arr[high] > sum) ? high--:low++;
}
return {};
}
int main()
{
vector<int> arr = {3,5,2,9,7,6,11,0};
int sum = 10;
auto ret = findPair2(arr,sum);
if(0 == ret.size()){
cout << "pair not found." << endl;
}
for(auto &iter : ret){
cout << iter << " ";
}
return 0;
}
方法三
第三种方法,可以借用map来解决,将数组的元素值和索引对应存储在map中,通过检查 sum-arr[i] 是否存在于map来确定想要的值。刚方法效率最高,只需要通过一次循环即可完成,所以时间复杂度为O (n).
上代码:
// 时间复杂度O(n) 空间复杂度 O(n)
vector<int> findPair3(vector<int> &arr,int sum)
{
std::map<int,int> tempMap;
for(int i = 0 ; i < arr.size()-1 ; ++i){
if(tempMap.find(sum - arr[i]) != tempMap.end()){
return {tempMap[sum - arr[i]],i};
}
tempMap[arr[i]] = i;
}
return {};
}
int main()
{
vector<int> arr = {3,5,2,9,7,6,11,0};
int sum = 10;
auto ret = findPair3(arr,sum);
if(0 == ret.size()){
cout << "pair not found." << endl;
}
for(auto &iter : ret){
cout << iter << " ";
}
return 0;
}
该题比较简单,主要考虑在不同的情况下其时间和空间复杂度的区别。闲来无事,就当练练手吧,保持思维的运转,哈哈哈~