找到无序数组中两值之和为key的所有组合
参考博客:https://blog.csdn.net/suibianshen2012/article/details/51923477
法1:穷举法,复杂度为O(n^2)
法2:先对数组进行快速排序(O(nlogn)),定义两个指针,一个从头到尾扫描,一个从尾部向头部扫描,每次都计算两指针对应元素之和,若等于key,跳出循环,若小于key,i++;若大于key,j–。
代码:
int findkey(int *a,int key)
{ int i=0,j=0;
for(i=0,j=n-1;i<j;)
{
if(a[i]+a[j]==key)
return (i,j);
else if(a[i]+a[j]<key)
i++;
else
j--;
}
return (-1,-1);
}
法3:哈希表。先遍历一次数组,存储每个数出现的次数,再遍历一次数组,对每个a[i],判断key-a[i]是否存在于哈希表中,如果存在的话,说明查找成功,否则的话继续遍历下一个。
int getSum(int *a, int len, int key)
{
hash_map<int, int> map;
//先遍历一遍数组,将每个数存在hashmap中,对应的value=1;表示存在次数
for(int i=0; i<len; i++)
map[a[i]] = 1;
//再遍历一遍数组,查看key-a[i]的是否在hashmap中,在则表示查找成功,不在则表示查找失败
//【若记录次数的话,每个数仅可用一次,则最后的cunt/2即为所求值】
flag=false;
for(int i=0; i<len; i++)
{
if(map[key-a[i]] == 1)
{
cunt++;
flag=true;//表示查找到了
}
}
if(flag==false)
return -1;
else
return cunt/2;
}
}
找到无序数组中第K大的数
参考博客:https://blog.csdn.net/acema/article/details/39695479
https://blog.csdn.net/yc461515457/article/details/51177812
法1:快速排序法
法2:堆排序法。先对前 k 个数进行建堆,堆顶为当前k个数组中最小的元素。时间复杂度O(k)。然后将第 k+1…n 个数依次和堆顶元素比较,如果新元素大于堆顶元素,则将它作为新的堆顶元素并调整最小堆,否则再处理下一个数。这样每一次循环都将保证最小堆中的k个数为当前最大的 k 个数。 时间复杂度O((n-k)*logk)。循环结束后,堆顶元素即是我们要找的第 k 大的数。算法总的时间复杂度是O(k+(n-k)*logk)。
法3:哈希表。若数组中的N个数都是[0,MAX) 之间的数(也就是数组A中数的范围类型都知道的),就可以用count[MAX]来记录每个整数出现的次数(count[i] 表示整数i在数组A中出现的次数)。我们只需扫描一遍数组就可以得到count数组,然后就可以找到第K大的数。
快速排序法最坏时间复杂度和平均时间复杂度
最坏情况的时间复杂度是当待排序的序列为正序或者逆序时O(n^2)
平均时间复杂度为O(nlogn)