一、常见的时间复杂度
- 时间复杂度:
由于计算机的性能不同,无法准确地统计出某个算法执行所需要的时间,所以我们使用算法执行的次数来代表算法的时间复杂度
O(频次) 一般忽略影响不大的常数 - 常见的时间复杂度
//O(1)
printf("%d",i);
//O(logn)
for(int i=n; i>=0; i/=2)
{
printf("%d",i);
}
//O(n)
for(int i=0; i<n; i++)
{
printf("%d",i);
}
//O(nlogn)
for(int i=0; i<n; i++)
{
for(int j=n; j>0; j/=2)
{
printf("%d",i);
}
}
//O(n^2)
for(int i=0; i<n; i++)
{
for(int j=0; j<n; j++)
{
printf("%d",i);
}
}
二、分治算法
把一个大而复杂的问题,分解成很多相同的小而简单的问题,利用计算机强大的计算能力来解决所有小问题,从而最终解决大问题。
- 实现分治的方法:循环、递归
注意:能用循环解决的问题,就不要用递归
三、查找算法
- 顺序查找
对待查找的数据没有要求,从头到尾逐一比较
适合在小规模的数据中使用,效率较低
时间复杂度:O(n) - 二分查找
待查找的数据必须有序,从数据中间的位置开始比较,如果中间值比key小则与右边部分的中间值继续比较,反之从左边比较,直到出结果为止。
时间复杂度:O(logn) - 哈希查找
数据 经过哈希函数 计算出数据在哈希表中的位置,然后标记,方便之后的查找,它的时间复杂度最好能到O(1)
但是该算法有很大的局限性,不适合浮点数、字符串数据,需要额外的存储空间,空间复杂度高,是一种典型的用空间换时间的算法。
哈希函数设计方法:
直接定址法:把数据直接当做数组的下标
数据分析法:分析数据的特点来设计哈希函数,常用的方法找到最大最小值,用 最大值-最小值+1 来确定哈希表的长度,用 数据-最小值 来访问哈希表 - 块查找(权重查找)
是一种处理数据的思想,不是一种特定的算法,当数据量特别多时,可以先把数据进行分块处理,然后再根据块条件进行查找。例如英文字典。
关于查找算法的题目:
1、二分查找
2、最长无重复子数组
3、给定一个字符串数组,再给定整数k,请返回出现次数前k名的字符串和对应的次数
4、统计一个数字在升序数组中出现的次数
5、旋转数组的最小数字
四、排序算法
时间复杂度 | 稳定性 | 特点 | |
---|---|---|---|
冒泡 | 最优:O(n) 平均:O(n^2) | 稳定 | 对数据的有序性敏感 |
选择 | O(n^2) | 不稳定 | 交换次数少 |
插入 | O(n^2) | 稳定 | 适合对已经排序好的数据 |
希尔 | O(n^2) | 不稳定 | 插入排序的升级版 |
快速 | O(nlogn) | 不稳定 | 综合性能最高 |
归并 | O(nlogn) | 稳定 | 需要使用额外的内存空间 |
堆 | O(nlogn) | 不稳定 | 调整成大顶堆 |
计数 | O(n+k) | 稳定 | 适合数据较为平均,重复数较多的排序 |
桶 | O(n+k) | 稳定 | 需要了解如何分桶、桶的范围定义多大 |
基数 | O(n+k) | 稳定 | 桶排序的具体实现 |
排序算法的题目:
1、最小的K个数
2、给定一个nums数组由一些非负整数组成,现需要将他们进行排列并拼接,每个数不可拆分,使得最后的结果最大,返回值需要是string类型,否则可能会溢出
3、合并区间