快速寻找满足条件的两个数
2015-12-06 16:18
246 查看
能否快速的在数组中找到两个数,让这两个数之和等于一个给定的数字。
解法1、
一个直接的解法就是穷举:从数组中任意取出两个数字,计算两者之和是否为
给定的数字。
显然其时间复杂度为N(n-1)/2即O(N^2)。这个算法很简单,写起来也很容
易,但是效率不高。一般在程序设计里面,要尽可能降低算法的时间和空间复杂度,
所以需要继续寻找效率更高的解法。
vector<double> mindifference(double arr[], int n, int num)
{
vector<double>result;
for (int i = 0; i < n; i++)
{
for (int j = i + 1; j < n; j++)
{
if (arr[i] + arr[j] == num)
{
result.push_back(arr[i]);
result.push_back(arr[j]);
break;
}
}
}
return result;
}
解法二
求两个数字之和,假设给定的和为Sum。一个变通的思路,就是对数组中的每个
数字arr[i]都判别Sum-arr[i]是否在数组中,这样,就变通成为一个查找的算法。
vector<double> mindifference(double arr[], int n, int num)
{
int index;
vector<double>result;
for (int i = 0; i < n; i++)
{
index = arr.find(num - arr[i]);
if (index != NULL)
{
result.push_back(arr[i]);
result.push_back(arr[index]);
break;
}
}
return result;
}
解法三
还可以换个角度来考虑问题,假设已经有了这个数组的任意两个元素之和的有
序数组(长为N^2)。那么利用二分查找法,只需用O(2*log2N)就可以解决这个
问题。当然不太可能去计算这个有序数组,因为它需要O(N^2)的时间。但这个思
考仍启发我们,可以直接对两个数字的和进行一个有序的遍历,从而降低算法的时
间复杂度。
首先对数组进行排序,时间复杂度为(N*log2N)。
然后令i = 0,j = n-1,看arr[i] + arr[j] 是否等于Sum,如果是,则结束。如果小于
Sum,则i = i + 1;如果大于大于Sum,则 j = j – 1。这样只需要在排好序的数组上遍
历一次,就可以得到最后的结果,时间复杂度为O(N)。两步加起来总的时间复杂
度O(N*log2N),下面这个程序就利用了这个思想,代码如下所示:
for (i = 0,j=n-1; i < n; i++)
{
if (arr[i] + arr[j] == num)
{
return (i, j);
}
else
{
if (arr[i] + arr[j] < sum)
{
i++;
}
else
{
j--;
}
}
}
解法1、
一个直接的解法就是穷举:从数组中任意取出两个数字,计算两者之和是否为
给定的数字。
显然其时间复杂度为N(n-1)/2即O(N^2)。这个算法很简单,写起来也很容
易,但是效率不高。一般在程序设计里面,要尽可能降低算法的时间和空间复杂度,
所以需要继续寻找效率更高的解法。
vector<double> mindifference(double arr[], int n, int num)
{
vector<double>result;
for (int i = 0; i < n; i++)
{
for (int j = i + 1; j < n; j++)
{
if (arr[i] + arr[j] == num)
{
result.push_back(arr[i]);
result.push_back(arr[j]);
break;
}
}
}
return result;
}
解法二
求两个数字之和,假设给定的和为Sum。一个变通的思路,就是对数组中的每个
数字arr[i]都判别Sum-arr[i]是否在数组中,这样,就变通成为一个查找的算法。
vector<double> mindifference(double arr[], int n, int num)
{
int index;
vector<double>result;
for (int i = 0; i < n; i++)
{
index = arr.find(num - arr[i]);
if (index != NULL)
{
result.push_back(arr[i]);
result.push_back(arr[index]);
break;
}
}
return result;
}
解法三
还可以换个角度来考虑问题,假设已经有了这个数组的任意两个元素之和的有
序数组(长为N^2)。那么利用二分查找法,只需用O(2*log2N)就可以解决这个
问题。当然不太可能去计算这个有序数组,因为它需要O(N^2)的时间。但这个思
考仍启发我们,可以直接对两个数字的和进行一个有序的遍历,从而降低算法的时
间复杂度。
首先对数组进行排序,时间复杂度为(N*log2N)。
然后令i = 0,j = n-1,看arr[i] + arr[j] 是否等于Sum,如果是,则结束。如果小于
Sum,则i = i + 1;如果大于大于Sum,则 j = j – 1。这样只需要在排好序的数组上遍
历一次,就可以得到最后的结果,时间复杂度为O(N)。两步加起来总的时间复杂
度O(N*log2N),下面这个程序就利用了这个思想,代码如下所示:
for (i = 0,j=n-1; i < n; i++)
{
if (arr[i] + arr[j] == num)
{
return (i, j);
}
else
{
if (arr[i] + arr[j] < sum)
{
i++;
}
else
{
j--;
}
}
}
相关文章推荐
- Hdu 5570 概率期望
- win8下建立wifi热点
- javaScript基础练习题-下拉框制作
- Android自定义GifView显示gif动画
- 使用Websocket+Swoole+CodeIngiter做聊天室
- openstack kvm 虚拟机磁盘差异衍生
- POJ 1823 Hotel(线段树)
- Android间进程通信
- php网站性能优化
- struts2中的ValueStack学习
- CDOJ 1255 斓少摘苹果 图论 2016_5_14
- 归并排序
- Ceph rgw CephContext _log属性
- java经典问题
- select
- 笨小熊
- 常见的Web开发者15条编码原则
- JS拖拽组件开发
- Java_31-40
- LINUX(UNIX)文件I/O学习