不断减少时间复杂度的一个例子
来源:互联网 发布:淘宝查看新品标签 编辑:程序博客网 时间:2024/05/01 00:53
问题:给出N张写有数字(k1, k2, ..., kn)的牌 和 一个数字M, 从中抽4次(每抽完一次要放回), 判断是否存在抽取4次牌上数字的和为M的组合是否存在。
1 <= n <= 1000, 1 <= m <= 10^9, 1 <= ki <= 10^6
输入:n = 3, m = 10, k = {1, 3, 5} n = 3, m = 9, k = {1, 3 , 5}
输出:yes(1, 1, 3, 5) no(不存在取4次和为9的情况啦)
(1)最容易想到的方法当然是暴力枚举啦, 那么抽取4次,那么就需要4层循环了,时间复杂度为O(n^4)
for (i = 0; i < n; i++) {for (j = 0; j < n; j++) {for (k = 0; k < n; k++) {for (l = 0; l < n; l++) {if (m == cards[i] + cards[j] + cards[k] + cards[l]) {flag = true;break ;}}}}} // O(n^4)题目输入范围可以到1000, 那么上面的将会超时啦。
(2)要判断是否m = cards[i] + cards[j] + cards[k] + cards[l], 那么可以判断cards[l] = m - cards[i] - cards[j] - cards[k]是否存在(二分查找)。O(n^3*logn)
int bin_search(int* arr, int left, int right, int key) {int mid;while (left <= right) {mid = (left + right)>>1;if (arr[mid] == key) {return mid;} else if (arr[mid] > key) {right = mid - 1;} else {left = mid + 1;}}return -1;}
sort(cards, cards + n);for (i = 0; i < n; i++) {for (j = 0; j < n; j++) {for (k = 0; k < n; k++) {key = m - cards[i] - cards[j] - cards[k];if (!flag && bin_search(cards, 0, n, key) > 0) {flag = true;}}}} // O(n^3*logn)
时间复杂度减小了, 但还是不能满足哦。
k = 0;for (i = 0; i < n; i++) {for (j = 0; j < n; j++) {nnCards[k++] = cards[i] + cards[j];}}sort(nnCards, nnCards + k);for (i = 0; i < n; i++) {for (j = 0; j < n; j++) {key = m - cards[i] - cards[j];if (!flag && bin_search(nnCards, 0, k, key) > 0) {flag = true;}}} // O(n^2*logn)好了, 时间复杂度降为O(n^2*logn^2)了, 但空间复杂度增加了, 需要一个存放n*n的数组, 那么1000*1000的话还是有点大了吧, 时间换空间?
这也算一种技巧,暴力搜索的时候多想想能不能降低时间复杂度吧。
- 不断减少时间复杂度的一个例子
- hdoj5281二分减少时间复杂度
- 时间复杂度 以及一些基本的例子
- 如何计算一个算法的时间复杂度和空间复杂度
- 如何计算一个算法的时间复杂度
- 如何计算一个算法的时间复杂度
- 计算一个算法的时间复杂度
- 如何计算一个算法的时间复杂度
- 如何计算一个算法的时间复杂度
- 从事体力劳动的人不断减少
- 334.leetcode Increasing Triplet Subsequence(medium)[巧妙的方法减少时间与空间复杂度]
- 对一个简单递归的 时间复杂度的分析
- 如何来求取一个算法的时间复杂度?
- 递归算法时间复杂度的计算方程式一个递归方程:
- 求一个数组的中位数时间复杂度为O(n)
- 通过一个实例学会时间复杂度的计算
- 时间复杂度的计算
- 时间复杂度的计算
- 8种Nosql数据库系统对比
- apk生成二维码
- Golden Gate 与 Oracle DataGuard的区别
- UVa:481 What Goes Up
- .net,C#,Ftp各种操作,上传,下载,删除文件,创建目录,删除目录,获得文件列表...
- 不断减少时间复杂度的一个例子
- 详细解析Java中抽象类和接口的区别
- Qt 事件和信号
- Android:LayoutInflater的使用
- [C++ Primer] 面向对象编程
- ARM混合编程笔记
- 不能豁出命去追求,只能永尝生活苦酒
- 扩张方法 this关键字
- Android 自动编译、打包生成apk文件 3 - 使用SDK Ant方式