快速寻找满足条件的两个数
2014-03-26 14:42
197 查看
能否快速找出一个数组中的两个数字,让这两个数字之和等于一个给定的值,为了简单化,假定数组中肯定存在至少一个符合要求的解。
解法一:穷举,从数组中任取两个数字,计算两者之和是否为给定值。时间复杂度为O(N^2)。
解法二:假定两数之和为sum,对数组中每个数字a[i],判断sum-a[i]是否在数组中,这样就变成了查找算法,如果在无序数组中查找要O(N)时间,所以总共还是O(N^2),转换一下,把数组变成有序的,查找可采用二分查找,这样就需要O(NlogN)时间。
解法三:先将数组排序,设置两个指针i=0,j=n-1,如果a[i]+a[j]==sum,则找到满足条件的,如果a[i]+a[j]<sum,i++,否则j--.
扩展:如果把这个两个数字改成三个数字或任意个数字。
如果是三个数字,比如a[i]+a[j]+a[k]==sum,可以先固定a[k],问题就转换成寻找两个数a[i]+a[k]=sum-a[k]及为上面的问题。这里查找需要O(N^2)时间。
任意个数字,采用递归算法,search(a,n-1,sum-a[n-1])或者search(a,n-1,sum)。
解法一:穷举,从数组中任取两个数字,计算两者之和是否为给定值。时间复杂度为O(N^2)。
解法二:假定两数之和为sum,对数组中每个数字a[i],判断sum-a[i]是否在数组中,这样就变成了查找算法,如果在无序数组中查找要O(N)时间,所以总共还是O(N^2),转换一下,把数组变成有序的,查找可采用二分查找,这样就需要O(NlogN)时间。
解法三:先将数组排序,设置两个指针i=0,j=n-1,如果a[i]+a[j]==sum,则找到满足条件的,如果a[i]+a[j]<sum,i++,否则j--.
void find(int *a,int n,int sum) { int i=0; int j=n-1; while(i<j) { if(a[i]+a[j]==sum) { cout<<i<<" "<<j<<endl; i++; j--; } else if(a[i]+a[j]>sum) j--; else i++; } }采用快排需要O(NlogN)时间,查找需要O(N)时间,所以总共O(NlogN)+O(N)=O(NlogN)。
扩展:如果把这个两个数字改成三个数字或任意个数字。
如果是三个数字,比如a[i]+a[j]+a[k]==sum,可以先固定a[k],问题就转换成寻找两个数a[i]+a[k]=sum-a[k]及为上面的问题。这里查找需要O(N^2)时间。
任意个数字,采用递归算法,search(a,n-1,sum-a[n-1])或者search(a,n-1,sum)。
相关文章推荐
- linux make menuconfig 执行流程小结
- Xming: No protocol specified
- isc-dhcp监听网口的实现步骤
- Android网络状态监听
- 获取android手机当前ip地址
- js 与或运算符 || && 妙用
- JavaScript的一些基础
- hevc
- Java Callable接口应用举例
- SOCI、LiteSQL、POCO数据库访问类库对比
- 记不起引用类型和值类型,在项目中让我犯糊涂,我真是菜鸟。
- 曲苑杂坛--数据库更新探秘
- java获取map中的最小KEY,最小VALUE
- 伊顿250万美元建中国客户体验中心
- Android判断屏幕是横屏还是竖屏
- .NTE 基础 之对象
- mysql 强大的trim() 函数
- iOS申请真机调试证书-图文详解
- C# Assembly.GetManifestResourceStream总返回 null问题
- 8 个很棒的免费的 C++ GUI 库