精华内容
下载资源
问答
  • 理解算法中的时间复杂度,O(1),O(n),O(log2n),O(n^2)

    千次阅读 多人点赞 2020-03-18 14:39:50
    算法复杂度分为时间复杂度和空间复杂度,二者也是衡量代码的好坏两个重要指标,常见时间复杂度排序为:O(1)<O(log2n)<On)<On^2)

    算法复杂度分为时间复杂度空间复杂度二者也是衡量代码的好坏两个重要指标:

    • 时间复杂度:指执行算法所需要的计算工作量;
    • 间复杂度:指执行这个算法所需要的内存空间。

    算法的复杂性体现在运行该算法时的计算机所需资源的多少上,计算机资源最重要的是时间和空间(即寄存器)资源,因此复杂度分为时间和空间复杂度。

    1. 概念理解

    1.1 基本执行次数:T(n)

    由于运行环境和输入规模的影响,代码的绝对执行时间是无法估计的,但我们可以估算出代码的基本执行次数。

    一般情况下,算法中基本操作重复执行的次数是问题规模n的某个函数,用这个函数来表达相对时间,可以记作 T(n)。

    1.2 时间复杂度:O(n)

    因为执行规则具有不确定性(文章下面就列举4种可能), 所以T(n) 不足以分析和比较一段代码的运行时间,就有了渐进时间复杂度(asymptotic time complexity)的概念,官方的定义如下:

    若存在函数 f(n),使得当n趋近于无穷大时,T(n)/ f(n)的极限值为不等于零的常数,则称 f(n)是T(n)的同数量级函数。记作 T(n)= O(f(n)),称O(f(n)) 为算法的渐进时间复杂度,简称:时间复杂度。

    渐进时间复杂度用大写“O”来表示,所以也被称为大O表示法。

    算法时间复杂度里有O(1), O(n), O(logn), O(nlogn), O(n^2)的概念,这是算法的时空复杂度的表示。

    它不仅仅用于表示时间复杂度,也用于表示空间复杂度

    O后面的括号中有一个函数,指明某个算法的耗时/耗空间与数据增长量之间的关系。其中的n代表输入数据的量

    1.3 空间复杂度:S(n)

    与时间复杂度类似,空间复杂度是指算法在计算机内执行时所需存储空间的度量,记作:S(n)=O(f(n)) 。

    上面提到过,O(n)不仅仅用于表示时间复杂度,也用于表示空间复杂度。

    2. 场景分析:

    这是针对时间复杂度的场景分析,时间复杂度排序为:O(1)< O(log2n)< O(n)< O(n^2)

    场景1:T(n) =  O(1)

    表示算法的运行时间为常量,这是最低的时空复杂度了,也就是耗时/耗空间与输入数据大小无关,无论输入数据增大多少倍,耗时/耗空间都不变。

    哈希算法就是典型的O(1)时间复杂度,无论数据规模多大,都可以在一次计算后找到目标(不考虑冲突的话)。

    场景2:T(n) =  O(log2n)

    当数据增大n倍时,耗时增大log n倍(这里的log是以2为底的,比如,当数据增大256倍时,耗时只增大8倍,是比线性还要低的时间复杂度)。

    二分查找就是O(log n)的算法,每找一次排除一半的可能,256个数据中查找只要找8次就可以找到目标。

    场景3:T(n) =  O(n)

    表示该算法是线性算法,数据量增大几倍,耗时也增大几倍。

    比如常见的for循环遍历,要找到一个数组里面最大的一个数,你要把n个变量都扫描一遍,操作次数为n,那么算法复杂度是O(n)。

    场景4:T(n) =  O(n^2)

    代表数据量增大n倍时,耗时增大n的平方倍,这是比线性更高的时间复杂度。

    比如冒泡排序,就是典型的O(n^2)的算法,对n个数排序,需要扫描n×n次。

    在编程的世界中有着各种各样的算法,除了上述的四个场景,还有许多不同形式的时间复杂度,我们按照时间复杂度,按数量级递增依次排列为:

    常数阶 O(1) <  对数阶(log2n) < 线性阶 O(n)<  线性对数阶 O(nlog2n) < 平方阶 O(n^2) < 立方阶 O(n^3) < k次方阶 O(n^k) < 指数阶 O(2^n)……

    3. 算法比较:

    排序算法

      平均时间

    最差情形

    稳定度

    额外空间

    备注

    冒泡

     O(n 2 )

     O(n 2 )

    稳定

    O(1)

    n 小时较好

    交换

      O(n 2 )

      O(n 2 )

    不稳定

    O(1)

    n 小时较好

    选择

     O(n 2 )

     O(n 2 )

    不稳定

    O(1)

    n 小时较好

    插入

     O(n 2 )

     O(n 2 )

    稳定

    O(1)

    大部分已排序时较好

    基数

    O(log R B)

    O(log R B)

    稳定

    O(n)

    B 是真数 (0-9) ,

    R 是基数 ( 个十百 )

    Shell

    O(nlogn)

    O(n s ) 1<s<2

    不稳定

    O(1)

    s 是所选分组

    快速

    O(nlogn)

    O(n 2 )

    不稳定

    O(nlogn)

    n 大时较好

    归并

    O(nlogn)

    O(nlogn)

    稳定

    O(1)

    n 大时较好

    O(nlogn)

    O(nlogn)

    不稳定

    O(1)

    n 大时较好

     

    借鉴了一些官方统计,再加上自己的理解,整理了一篇比较全面的关于介绍时间复杂度的博客,内容涵盖了从概念延伸到原理,再到算法的总结,希望对大家有一定的帮助。

     

    少侠请留步 ... ヾ(◍°∇°◍)ノ゙ ... 
    欢迎点赞、评论、加关注,让更多人看到学到赚到
    更多精彩,请关注我的"今日头条号":Java云笔记

    展开全文
  • 一篇文章让你彻底了解算法的时间复杂度O(n)!!!

    千次阅读 多人点赞 2019-11-19 15:39:20
    时间频度:一个算法花费的时间与算法中语句的执行次数成正比例,哪个算法中语句执行次数多,它花费时间 就多。一个算法中的语句执行次数称为语句频度或时间频度。记为 T(n)。[举例说明] 比如计算 1-100 所有数字之和...

    一、时间频度

    基本介绍:
    时间频度:一个算法花费的时间与算法中语句的执行次数成正比例,哪个算法中语句执行次数多,它花费时间 就多。一个算法中的语句执行次数称为语句频度或时间频度。记为 T(n)。[举例说明]
    比如计算 1-100 所有数字之和, 我们设计两种算法:
    在这里插入图片描述


    举例说明-忽略常数项
    在这里插入图片描述

    结论:

    1) 2n+20 和 2n 随着 n 变大,执行曲线无限接近, 20 可以忽略
    2) 3n+10 和 3n 随着 n 变大,执行曲线无限接近, 10 可以忽略


    举例说明-忽略低次项
    在这里插入图片描述

    结论:

    1) 2n^2 +3n+10 和 2n^2 随着 n 变大, 执行曲线无限接近, 可以忽略 3n+10
    2) n^2+5n+20 和 n^2 随着 n 变大,执行曲线无限接近, 可以忽略 5n+20


    举例说明-忽略系数
    在这里插入图片描述

    结论:

    1) 随着 n 值变大,5n^2+7n 和 3n^2 + 2n ,执行曲线重合, 说明 这种情况下, 5 和 3 可以忽略。
    2) 而 n^3+5n 和 6n^3+4n ,执行曲线分离,说明多少次方式关键


    二、时间复杂度

    1. 一般情况下,算法中的基本操作语句的重复执行次数是问题规模 n 的某个函数,用 T(n)表示,若有某个辅 助函数 f(n),使得当 n 趋近于无穷大时,T(n) / f(n) 的极限值为不等于零的常数,则称 f(n)是 T(n)的同数量级函数。 记作 T(n)=O( f(n) ),称O( f(n) ) 为算法的渐进时间复杂度,简称时间复杂度。

    2. T(n) 不同,但时间复杂度可能相同。 如:T(n)=n²+7n+6 与 T(n)=3n²+2n+2 它们的 T(n) 不同,但时间复杂 度相同,都为 O(n²)

    3) 计算时间复杂度的方法:

    • 用常数 1 代替运行时间中的所有加法常数 T(n)=3n²+7n+6 => T(n)=3n²+7n+1
    • 修改后的运行次数函数中,只保留最高阶项 T(n)=3n²+7n+1 => T(n) =3n²
    • 去除最高阶项的系数 T(n) = n² => T(n)

    三、常见的时间复杂度:

    1. 常数阶 O(1)
    2. 对数阶 O(log2n)
    3. 线性阶 O(n)
    4. 线性对数阶 O(nlog2n)
    5. 平方阶 O(n^2)
    6. 立方阶 O(n^3)
    7. k 次方阶 O(n^k)
    8. 指数阶 O(2^n)

    常见的时间复杂度对应的图:
    在这里插入图片描述
    说明:

    1. 常见的算法时间复杂度由小到大依次为:Ο(1)<Ο(log2n)<Ο(n)<Ο(nlog2n)<Ο(n2)<Ο(n3)< Ο(nk) < Ο(2n) ,随着问题规模 n 的不断增大,上述时间复杂度不断增大,算法的执行效率越低
    2. 从图中可见,我们应该尽可能避免使用指数阶的算法

    1) 常数阶 O(1)

    在这里插入图片描述


    2) 对数阶 O(log2n)
    在这里插入图片描述


    3) 线性阶 O(n)

    在这里插入图片描述


    4) 线性对数阶 O(nlogN)
    在这里插入图片描述


    5) 平方阶 O(n²)
    在这里插入图片描述


    6) 立方阶 O(n³)、K 次方阶 O(n^k)
    说明:参考上面的 O(n²) 去理解就好了,O(n³)相当于三层 n 循环,其它的类似


    四、平均时间复杂度和最坏时间复杂度

    1. 平均时间复杂度是指所有可能的输入实例均以等概率出现的情况下,该算法的运行时间。
    2. 最坏情况下的时间复杂度称最坏时间复杂度。一般讨论的时间复杂度均是最坏情况下的时间复杂度。这样做的 原因是:最坏情况下的时间复杂度是算法在任何输入实例上运行时间的界限,这就保证了算法的运行时间不会 比最坏情况更长。
    3. 平均时间复杂度和最坏时间复杂度是否一致,和算法有关(如图:)

    在这里插入图片描述


    展开全文
  • 去年写了一篇《分治算法 求第k小元素 O(n)》的文章。介绍了一种对快排进行改进的算法,可以在时间复杂度O(n)的情况下,找到第k小的数字。那时候,我还不知道这个算法叫BFPRT算法——现在知道了,还知道它又被称为中...

    我自己搭建了博客,以后可能不太在CSDN上发博文了,https://www.qingdujun.com/


    去年写了一篇《分治算法 求第 k k k小元素 O ( n ) O(n) O(n) & O ( n l o g 2 n O(nlog2^n O(nlog2n)》的文章。介绍了一种对快排进行改进的算法,可以在时间复杂度 O ( n ) O(n) O(n)的情况下,找到第 k k k小的数字。

    那时候,我还不知道这个算法叫BFPRT算法——现在知道了,还知道它又被称为中位数的中位数算法,它的最坏时间复杂度为 O ( n ) O(n) O(n) ,它是由Blum、Floyd、Pratt、Rivest、Tarjan提出,它的思想是修改快速选择算法的主元选取方法,提高算法在最坏情况下的时间复杂度。

    1 STL std::nth_element

    而且,我还发现了STL中有一个类似的函数——std::nth_element (位于头文件<algorithm>中):
    http://www.cplusplus.com/reference/algorithm/nth_element/

    #include <iostream>
    #include <vector>
    #include <algorithm>
    #include <functional>
    
    int main() {
        std::vector<int> v{5, 6, 4, 3, 2, 6, 7, 9, 3};
        std::nth_element(v.begin(), v.begin() + v.size()/2, v.end());
        std::cout << "The median is " << v[v.size()/2] << '\n';
        std::nth_element(v.begin(), v.begin()+1, v.end(), std::greater<int>());
        std::cout << "The second largest element is " << v[1] << '\n';
    }
    

    The median is 5
    The second largest element is 7

    2 BFPRT算法(中位数的中位数算法)

    好了,言归正传。BFPRT算法主要由两部分组成(快排、基准选取函数)。基准选取函数也就是中位数的中位数算法(Median of Medians algorithm)的实现,具体来说——就是将快排中基准选取策略进行了优化,改为每次尽可能的选择中位数作为基准。

    那么是如何尽可能的选出中位数? 如果要找到一个精确的中位数,所消耗的时间代价将得不偿失,而且对于快排算法来说,只要基准尽可能的接近真正的中位数,就能形成近似的均分。我在上一篇文章中举了个例子,这里我再重复一遍:

    2.1 举个例子

    假设,我们要找arr[18]的近似中位数——其实,也就是找到数字8。(注意到,由于使用了分组,这里产生的只是尽可能的中位数)

    int arr[18] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18 };
    

    BFPRT算法规定了,将5个元素作为一组(选出中位数)。然后,再选出中位数中的中位数…一直到,最终选出一个数字。

    那么,第一轮就是这样(将选出的中位数放置在最前面):

    //执行momedians之前
    { 1,2,3,4,5} {6,7,8,9,10} {11,12,13,14,15} {16,17,18 };
    

    分别对每组sort后选取小组中位数,再使用swap将小组中位数放置在“最前面”对应位置(注意下文中*号的标注,它表示这一步选出的小组中位数放置到哪儿去了)。

    //开始momedians
    { 3*,2,1*,4,5};//sort->swap(3,1)
    { 3,8*,1,4,5} {6,7,2*,9,10};//sort->swap(8,2)
    { 3,8,13*,4,5} {6,7,2,9,10} {11,12,1*,14,15};//sort->swap(13,1)
    { 3,8,13,17*,5} {6,7,2,9,10} {11,12,1,14,15} {16,4*,18 };//sort->swap(17,4)
    

    同样,第二轮初始时就成如下样子了,很显然已经少于5个数字了:

    //执行momedians之前
    { 3,8,13,17};
    

    直接选出中位数8

    2.2 算法实现(c++)

    可以将上述过程使用C++代码描述如下(对于5个数字的排序,使用Insert sort可能会效率更高)。再次强调,下面这段代码唯一的作用,就是用来选出每次快排的基准:

    //Median of Medians algorithm
    int momedians(int* const low, int* const high) {
    	if (low >= high - 1) {
    		return *low;
    	}
    	//int grp_length = (int)std::sqrt(high - low);
    	int grp_length = 5, grp_idx = 0;
    	for (int* l = low, *r; l < high; l = r+1) {
    		r = (l + grp_length >= high) ? high : l + grp_length - 1;
    		std::sort(l, r); //可以使用下文的void isort(int* const low, int* const high)
    		std::swap(*(low+grp_idx++), *(l + (r - l) / 2));
    	}
    	return momedians(low, low + grp_idx);
    }
    

    写到这里已经将BFPRT算法核心介绍完毕了。

    如果想测试使用Insert sort是否会带来效率上提升的小伙伴,可以试试下面这段代码insert_sort,尝试着替换文中的std::sort排序函数。

    //Insert sort
    void insert_sort(int* const low, int* const high) {
    	for (int* i = low + 1; i <= high; ++i) {
    		if (*i < *(i-1)) {
    			int border = *i, *j = i-1;
    			for ( ; border < *j; --j) {
    				*(j+1) = *j;
    			}
    			*(j+1) = border;
    		}
    	}
    }
    

    让我们思维次再回到momedians函数。从上述代码中可以看到grp_length = 5是一个固定值。那么,在BFPRT算法中,为什么是选5个作为分组? 这个我也不是很明白,我也尝试使用sqrt(数组长度)作为分组的长度。

    有兴趣的可以阅读 ACdreamer 的一篇《BFPRT算法原理》,他在文章结尾处,对为什么使用5作为固定分组长度进行了简单说明。同时,还附有BFPRT算法的最坏时间复杂度为 O ( n ) O(n) O(n) 的证明。

    好了,以下为完整的“BFPRT算法:时间复杂度 O ( n ) O(n) O(n)求第k小的数字”代码。如上文所说,算法主体功能是快排,只是在基准选取的时候使用了momedians算法——而不是直接取第一个数作为基准(严蔚敏版教材中的做法)。

    #include <iostream>
    #include <algorithm>
    using namespace std;
    
    //Median of Medians algorithm
    int momedians(int* const low, int* const high) {
    	if (low >= high - 1) {
    		return *low;
    	}
    	int grp_length = 5, grp_idx = 0;
    	for (int* l = low, *r; l < high; l = r+1) {
    		r = (l + grp_length >= high) ? high : l + grp_length - 1;
    		std::sort(l, r);
    		std::swap(*(low+grp_idx++), *(l + (r - l) / 2));
    	}
    	return momedians(low, low + grp_idx);
    }
    
    //Quick sort
    int qsort(int* const low, int* const high, int* const ptrk) {
    	int* l = low, *r = high;
    	if (l < r) {
    		int pivot = momedians(l, r);
    		while (l < r) {
    			while (l < r && *r >= pivot) {
    				--r;
    			}
    			*l = *r;
    			while (l < r && *l <= pivot) {
    				++l;
    			}
    			*r = *l;
    		}
    		*r = pivot;
    	}
    	//per qsort end, check left == right == ptrk?
    	return r == ptrk ? *ptrk :
    		(r > ptrk ?
    			qsort(low, r - 1, ptrk) :
    			qsort(r + 1, high, ptrk));
    }
    
    //Blum、Floyd、Pratt、Rivest、Tarjan
    int bfprt(int* const low, int* const high, const int k = 1) {
    	if (low >= high || k < 1 || k > high - low) {
    		throw std::invalid_argument("low > high || k < 1");
    	}
    	return qsort(low, high-1, low + k -1);//[low, high)
    }
    
    int main() {
    	int arr[18] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18 };
    	//cout << bfprt(&arr[0], &arr[0]+1, 1) << endl;
    	cout << bfprt(&arr[0], &arr[0] + 18, 18) << endl;
    
    	return 0;
    }
    

    以上的代码是针对int数组编写的,下面再测试一下对于其他类型的支持情况(这里直接粗暴的加上了一个模板)。有一点想强调的是,这里的bfprt函数参数是左闭右开区间[low,high),同时k必须是从1开始的正数。

    //Blum、Floyd、Pratt、Rivest、Tarjan
    template<typename T>
    T bfprt(T* const low, T* const high, const int k = 1) {
    	if (low >= high || k < 1 || k > high - low) {
    		throw std::invalid_argument("low > high || k < 1");
    	}
    	return qsort(low, high-1, low + k -1);//[low, high)
    }
    

    main函数中对intcharstring类型进行了测试。完整代码如下…

    #include <iostream>
    #include <algorithm>
    using namespace std;
    
    //Median of Medians algorithm
    template<typename T>
    T momedians(T* const low, T* const high) {
    	if (low >= high - 1) {
    		return *low;
    	}
    	int grp_length = 5, grp_idx = 0;
    	for (T* l = low, *r; l < high; l = r+1) {
    		r = (l + grp_length >= high) ? high : l + grp_length - 1;
    		std::sort(l, r);
    		std::swap(*(low+grp_idx++), *(l + (r - l) / 2));
    	}
    	return momedians(low, low + grp_idx);
    }
    
    //Quick sort
    template<typename T>
    T qsort(T* const low, T* const high, T* const ptrk) {
    	T* l = low, *r = high;
    	if (l < r) {
    		T pivot = momedians(l, r);
    		while (l < r) {
    			while (l < r && *r >= pivot) {
    				--r;
    			}
    			*l = *r;
    			while (l < r && *l <= pivot) {
    				++l;
    			}
    			*r = *l;
    		}
    		*r = pivot;
    	}
    	//per qsort end, check left == right == ptrk?
    	return r == ptrk ? *ptrk :
    		(r > ptrk ?
    			qsort(low, r - 1, ptrk) :
    			qsort(r + 1, high, ptrk));
    }
    
    //Blum、Floyd、Pratt、Rivest、Tarjan
    template<typename T>
    T bfprt(T* const low, T* const high, const int k = 1) {
    	if (low >= high || k < 1 || k > high - low) {
    		throw std::invalid_argument("low > high || k < 1");
    	}
    	return qsort(low, high-1, low + k -1);//[low, high)
    }
    
    int main() {
    	int arr[18] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18 };
    	cout << bfprt(&arr[0], &arr[0] + 18, 18) << endl;
    
    	char str[7] = {'a','b','c','d','e','f','g'};
    	cout << bfprt(&str[0], &str[0] + 7, 4) << endl;
    
    	string s = "abcdefghijklmnopqrstuvwxyz";
    	cout << bfprt(&s[0], &s[0] + 26, 10) << endl;
    	
    	return 0;
    }
    



    ©qingdujun
    2018-12-25 北京 海淀


    References:
    [1] 为径,分治算法 求第k小元素 O ( n ) O(n) O(n) & O ( n l o g 2 n ) O(nlog2^n) O(nlog2n) ,2018-12-25
    [2] ACdreamer,BFPRT算法原理 ,2018-12-25
    [3] STL nth_element() , 2018-12-25

    展开全文
  • Big O notation 算法复杂度计算方法

    千次阅读 2019-06-30 18:34:03
    文章目录常见的算法复杂度O(1)O(N)O(N^2)O(logN)O(2^n)O(n!)时间复杂度对比 Big O notation大零符号一般用于描述算法的复杂程度,比如执行的时间或占用内存(磁盘)的空间等,特指最坏时的情形。 常见的算法复杂度 O...


    Big O notation大零符号一般用于描述算法的复杂程度,比如执行的时间或占用内存(磁盘)的空间等,特指最坏时的情形。

    常见的算法复杂度

    O(1):Constant Complexity 常数复杂度
    O(N):线性时间复杂度
    O(N^2):N square Complexity 平方
    O(N^3):N square Complexity 立方
    O(2^N):Logarithmic Complexity 对数复杂度
    O(logN) :Exponential Growth 指数
    O(n!) :Factorial阶乘

    注意:只看最高复杂度的运算

    O(1)

            int n = 1000;
            System.out.println(n);
    

    上面两行代码的算法复杂度即为O(1)。

            int n = 1000;
            System.out.println(n);
            System.out.println(n);
            System.out.println(n);
    

    由于只看最高复杂度的运算,所以上面四行代码的算法复杂度也为O(1)。

    O(N)

            for (int i = 0; i < n; i++) {
                System.out.println(i);
            }
    

    以上代码复杂度为O(N)。

    O(N^2)

            for (int i = 0; i < n; i++) {
                for (int j = 0; j < n; j++) {
                    System.out.println(j);
                }
            }
    

    这里有两个嵌套的for循环,所以执行最多的次数肯定为两个for循环次数相乘,即N*N(N等于elements长度),所以这个函数的复杂度为O(N^2)。

    O(logN)

    是不是一看log(对数)就头大,其实没那么复杂,在看例子前我们先复习复习高中知识,什么是log。

    如果x的y次方等于n(x>0,且x不等于1),那么数y叫做以x为底n的对数(logarithm)。 记作logxN=y。其中,x叫做对数的底数。

    1. 底数为10时,写为lg;
    2. 底数为e时,称为自然对数写为ln,这个在高等数学中用的很多;
    3. 底数为2时,主要用在计算机中,写为log,也就是不写底数;

    所以我们说的logN其实就是log2N。

            for (int i =2; i < n; i*=2) {
                System.out.println(i);
            }
    

    以上算法的的复杂度即为logN,二分查找法(Binary Search)的复杂度也为logN。

    O(2^n)

            for (int i = 2; i < Math.pow(2,n); i++) {
                System.out.println(i);
            }
    

    以上算法的的复杂度即为2N,通过递归的方式计算斐波那契数的复杂度也为2N。

    O(n!)

            //factorial:阶乘
            for (int i = 2; i < factorial(n); i++) {
                System.out.println(i);
            }
    

    以上算法的的复杂度即为2N,通过递归的方式计算斐波那契数的复杂度也为2N。

    时间复杂度对比

    时间复杂度

    展开全文
  • 分治算法 求第k小元素 O(n) & O(nlog2^n)

    万次阅读 多人点赞 2017-11-22 17:32:45
    BFPRT算法:时间复杂度O(n)求第k小的数字(分治算法+快排)   各位小伙伴,由于本篇文章代码太过杂乱。我于 2018年12月25日 对文中介绍的算法进行了重写。点击上面的蓝色字体,可以阅读重写后的文章,修复了一些...
  • 在描述算法复杂度时,经常用到O(1)、O(n)、O(logn)、O(nlogn)来表示对应算法的时间复杂度, 这里进行归纳一下它们代表的含义: O后面的括号中有一个函数,指明某个算法的耗时/耗空间与数据增长量之间的关系。其中的n...
  • O(n)复杂度的排序算法

    千次阅读 2016-02-25 15:42:44
    计数排序,基数排序,桶排序,寻找第k个最大最小值算法-----java实现
  • 时间复杂度为O(n)的排序算法

    千次阅读 2019-06-27 10:34:42
    看上去似乎任何已知的算法都无法做到,如果谁做到了,那么所有的排序方法:QuickSort,ShellSort,HeapSort,BubbleSort等等等等,都可以扔掉了,还要这些算法干吗阿,呵呵。 不过实际上,在数字范围有限制的情况下...
  • 在学习数据结构的过程中,时间复杂度是我们最先接触到的概念,我们一般用时间复杂度判断算法的优劣, 但是课本中并没有详细介绍各种代码时间复杂度的例子,因此,这里对常见的时间复杂度以及代码实例举一些例子,供...
  • 算法的时间复杂度(大O表示法)

    千次阅读 2020-10-31 16:44:50
    下面我们来看下两种简单的方法(方法有很多种),再来引入算法的运行时间!`` 方法一(循环遍历): 假设你从1开始依次往上猜,猜测过程会是这样! 这是简单查找,更准确的说法是傻找。每次猜测都只能排除一个数字。...
  • 时间复杂度为O(N)的排序算法主要有三种——桶排序、计数排序与基数排序,后两者是基于桶排序的思想1.桶排序·基本思想 给定一个数组arr,数组内都是整数,整数都是处于0到9之间的。于是可以定义一个大小为10的数组b...
  • 在描述算法复杂度时,经常用到o(1), o(n), o(logn), o(nlogn)来表示对应算法的时间复杂度。这里进行归纳一下它们代表的含义:这是算法的时空复杂度的表示。不仅仅用于表示时间复杂度,也用于表示空间复杂度。   O后面...
  • 时间复杂度为On)的排序算法

    千次阅读 2018-11-24 12:57:04
    冒泡排序,选择排序,它们已经是相对比较简单,稳定的排序算法了,但是它们时间复杂度为On*n),基本都要用到两层循环,今天我就像大家介绍一种简单,只用一层for循环,时间复杂度为O(n)的排序算法。 样例输入:1 ...
  • 问题描述采用动态规划策略设计并实现算法,求解最大子段和及最大子段和的起始下标和终止下标,要求算法的时间复杂性不超过O(n)。最大子段和问题给定由n个整数(可能为负整数)组成的序列a1, a2,…, an, 求该序列形如...
  • https://www.cnblogs.com/TangBiao/p/5856695.html https://blog.csdn.net/dazhaoDai/article/details/81631195 ... 算法复杂度分析 为什么要进行算法分析? 预测算法所需的资源 计算时间(CPU...
  • 相信很多开发的同伴们在研究算法、排序的时候经常会碰到O(1),O(n),O(logn),O(nlogn)这些复杂度,看到这里就会有个疑惑,这个O(N)到底代表什么呢?带着好奇开始今天文章。      &...
  • 关于算法的时间复杂度O(f(n))

    千次阅读 2019-01-31 17:19:13
    算法的时间复杂度,也就是算法的时间量度,记作:T(n)=O(f(n))。它表示随问题规模n的增大,算法执行时间的增长率和f(n)的增长率相同,称作算法的渐进时间复杂度,简称时间复杂度。其中f(n)是问题规模n的某个函数。 ...
  • O算法

    万次阅读 2018-09-23 22:39:02
    O计法:根据执行次数计算 #sum = (1+n)*n/2;//执行了一次,即为O(1) #for(i=0;i&lt;...算法的时间复杂度:T(n) = O(f(n)) 常数阶:O(1) 线性阶:O(n) 对数阶:O(log2n)  平方阶:O(n*n)...
  • 《数据结构与算法》—— O(3N)=O(N) ?

    千次阅读 2020-03-01 21:03:50
    数据结构与算法的重要概念阐述
  • 问题描述:设有一个正整数序列a[n]a[n]: a1,a2,...,ana_1, a_2, ..., a_n ,对于下标i1i2...ihi_1 ,若有ai1,ai2,...,aiha_{i_1}, a_{i_2}, ..., a_{i_h}, 则称序列a[n]a[n]含有一个长度为h的不下降子序列。...
  • 算法中的O(1), O(n),O(logn), O(nlogn)分别是什么意思?

    千次阅读 多人点赞 2020-04-02 19:04:08
    描述算法复杂度时,常用o(1), o(n), o(logn), o(nlogn)表示对应算法的时间复杂度,是算法的时空复杂度的表示。不仅仅用于表示时间复杂度,也用于表示空间复杂度。 O后面的括号中有一个函数,指明某个算法的耗时/耗...
  • 算法中的时间复杂度O(n)详解例题

    千次阅读 2019-07-14 18:25:13
    以下T(n)表示各算法中最耗时操作的执行次数,n表示数据量,请按照时间复杂度从小到大排列,正确的是()。 T1(n) = 100n + 200 T2(n) = 3n^2 T3(n) = 10000000 T4(n) = 300 A. T1<T2<T3<T4 B.T2<T1&...
  • 将整个数组排序再选择第k个数的时间复杂度是O(nlog(n)),快速选择算法将平均时间复杂度优化到O(n),但最坏的情况还是O(n^2)。一开始很纠结这个O(n)是怎么来的,后来看了一下别人的分析,得到了答案。 二、分析 ...
  • 提出问题(在做功能时遇到的):为什么,O(1)、O(n)的概念又是什么 Java中 Set 和 List 集合 的contains()方法,检查数组链表中是否包含某元素 检查数组链表中是否包含某元素,使用 Set 而不使用 List 的原因是效率...
  • 算法分析—大O、大Ω、大θ

    万次阅读 多人点赞 2019-01-24 18:06:46
    简介 在算法的学习中,最开始便是要学习算法的分析。学习算法分析时,我们便会接触到这么几个符号:大O、大Ω、大θ、小o、小ω。...在表示一个算法时间复杂度时,我们常用如**T(n)=O(n^2)**的形式表示,而在...
  • 找中位数O(n)算法

    万次阅读 2015-07-21 10:09:29
    中位数是排序后数组的中间值,如果数组的个数是偶数个,则返回排序后数组的第N/2个数。 样例 给出数组[4, 5, 1, 2, 3], 返回 3 给出数组[7, 9, 4, 5],返回 5 解题思路: 利用快排划分的思想,递归...
  • 时间复杂度算法分析同一问题可用不同算法解决,而一个算法的质量优劣将影响到算法乃至程序的效率.算法分析的目的在于选择合适算法和改进算法.一个算法的评价主要从时间复杂度和空间复杂度来考虑.1、时间复杂度(1)...
  • 基本思想:依次比较相邻元素,若前面的大于后面的就交换元素,在一次迭代中将最大的元素“沉降”到最后的位置,经过n-1次迭代即可完成排序目的。 public static void bubbleSort(int[] data) { for(int i=0;i<...
  • 在描述算法复杂度时,经常用到o(1), o(n), o(logn), o(nlogn)来表示对应算法的时间复杂度, 这里进行归纳一下它们代表的含义: 这是算法的时空复杂度的表示。不仅仅用于表示时间复杂度,也用于表示空间复杂度。 O...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 672,023
精华内容 268,809
关键字:

O(n)算法