编程题练习(3)

找到无序数组中两值之和为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)

堆排序思想

参考博客:https://www.cnblogs.com/chengxiao/p/6129630.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值