(七)算法面试必问

列举出常见排序算法

非线性时间比较类排序:通过比较来决定元素间的相对次序。时间复杂度不能突破O(nlogn)而得此名称。

线性时间非比较类排序:不能通过比较来决定元素间的相对次序。它可以突破比较排序的时间下限,以线性时间运行而得此称。

会写常见的排序算法(如快排、归并)吗?

https://blog.csdn.net/zl_StepByStep/article/details/80098718

 

 

各种排序算法的时间复杂度、稳定性(重点:快排)。

排序算法平均时间复杂度最坏时间复杂度空间复杂度是否稳定
冒泡排序O(n²)O(n²)O(1)
选择排序O(n²)O(n²)O(1)
直接插入排序O(n²)O(n²)O(1)
归并排序O(nlogn)O(nlogn)O(n)
快速排序O(nlogn)O(O(logn)
堆排序O(nlogn)O(nlogn)O(1)
希尔排序O(nlogn)O(n^s)O(1)
计数排序O(n+k)O(n+k)O(n+k)
基数排序O(N∗M)O(N∗M)O(M)

1 归并排序可以通过手摇算法将空间复杂度降到O(1),但是时间复杂度会提高。

2 基数排序时间复杂度为O(N*M),其中N为数据个数,M为数据位数。

辅助记忆

时间复杂度:

  • 冒泡、选择、直接...排序需要两个for循环,每次只关注一个元素,平均时间复杂度为O(n2)(一遍找元素O(n),一遍找位置O(n))
  • 快速、归并、希尔、堆基于二分思想,log以2为底,平均时间复杂度为O(nlogn)O(nlogn)(一遍找元素O(n)O(n),一遍找位置O(logn)O(logn))

稳定性:

   •   排序算法的稳定性:排序前后相同元素的相对位置不变,则称排序算法是稳定的;否则排序算法是不稳定的。

 

快速排序动图:

 

单链表的遍历和逆序?

    这是很经典的“单链表逆序”问题。很多公司的面试题库中都有这道题,有的公司明确题目要求不能开辟额外的节点空间,有的没有明确说明,但是如果面试者使用了额外的节点存储空间,会得到一个比较低的分数。

https://www.cnblogs.com/jsczljh/p/3765720.html

 

深度优先搜索和广度优先搜索

http://www.cnblogs.com/skywang12345/p/3711483.html

 

最小生成树

补充几个关于吐得概念:

  • 连通图:在无向图中,若任意两个顶点vivi与vjvj都有路径相通,则称该无向图为连通图。
  • 强连通图:在有向图中,若任意两个顶点vivi与vjvj都有路径相通,则称该有向图为强连通图。
  • 连通网:在连通图中,若图的边具有一定的意义,每一条边都对应着一个数,称为权;权代表着连接连个顶点的代价,称这种连通图叫做连通网。
  • 生成树:一个连通图的生成树是指一个连通子图,它含有图中全部n个顶点,但只有足以构成一棵树的n-1条边。一颗有n个顶点的生成树有且仅有n-1条边,如果生成树中再添加一条边,则必定成环。
  • 最小生成树:在连通网的所有生成树中,所有边的代价和最小的生成树,称为最小生成树。 è¿éåå¾çæè¿°

普里姆(Prim)算法和克鲁斯卡尔(Kruskal)算法+C语言实现:https://blog.csdn.net/qq_35644234/article/details/59106779

Java代码实现:https://blog.csdn.net/witsmakemen/article/details/8889256

 

 

常见的Hash算法,哈希的原理和代价。

    实际开发中我们经常用到Hashtable(哈希表/散列表)这种结构,当遇到键-值对存储,采用Hashtable比ArrayList查找的性能高。原因是哈希查找是通过计算数据元素的存储地址进行查找的一种方法。O(1)的查找,即所谓的秒杀。哈希查找的本质是先将数据映射成它的哈希值。哈希查找的核心是构造一个哈希函数,它将原来直观、整洁的数据映射为看上去似乎是随机的一些整数。

常用的构造散列函数的方法:

    1. 直接寻址法:取关键字或关键字的某个线性函数值为散列地址。即H(key)=key或H(key) = a•key + b,其中a和b为常数(这种散列函数叫做自身函数)

 2. 数字分析法:分析一组数据,比如一组员工的出生年月日,这时我们发现出生年月日的前几位数字大体相同,这样的话,出现冲突的几率就会很大,但是我们发现年月日的后几位表示月份和具体日期的数字差别很大,如果用后面的数字来构成散列地址,则冲突的几率会明显降低。因此数字分析法就是找出数字的规律,尽可能利用这些数据来构造冲突几率较低的散列地址。

 3. 平方取中法:取关键字平方后的中间几位作为散列地址。

 4. 折叠法:将关键字分割成位数相同的几部分,最后一部分位数可不同,再取这几部分的叠加和(去除进位)作为散列地址。

 5. 随机数法:选择一随机函数,取关键字的随机值作为散列地址,通常用于关键字长度不同的场合。

 6. 除留余数法:取关键字被某个不大于散列表表长m的数p除后所得的余数为散列地址。即 H(key) = key MOD p, p<=m。不仅可以对关键字直接取模,也可在折叠、平方取中等运算之后取模。对p的选择很重要,一般取素数或m,若p选的不好,容易产生同义词。

构造好了哈希函数之后,就是哈希查找,操作步骤如下

1) 用给定的哈希函数构造哈希表;

2) 根据选择的冲突处理方法,解决地址冲突;

3) 在哈希表的基础上执行哈希查找。

 

建立哈希表操作步骤

     1) step1 取数据元素的关键字key,计算其哈希函数值(地址)。若该地址对应的存储空间还没有被占用,则将该元素存入;否则执行step2解决冲突。

    2) step2 根据选择的冲突处理方法,计算关键字key的下一个存储地址。若下一个存储地址仍被占用,则继续执行step2,直到找到能用的存储地址为止。

哈希查找步骤为

    1) Step1 对给定k值,计算哈希地址 Di=H(k);若HST为空,则查找失败;若HST=k,则查找成功;否则,执行step2(处理冲突)。

    2) Step2 重复计算处理冲突的下一个存储地址 Dk=R(Dk-1),直到HST[Dk]为空,或HST[Dk]=k为止。若HST[Dk]=K,则查找成功,否则查找失败。

 

解决冲突的方法有以下两种:  

(1)   开放地址法  

     如果两个数据元素的哈希值相同,则在哈希表中为后插入的数据元素另外选择一个表项。当程序查找哈希表时,如果没有在第一个对应的哈希表项中找到符合查找要求的数据元素,程序就会继续往后查找,直到找到一个符合查找要求的数据元素,或者遇到一个空的表项。  

(2)   链地址法

     将哈希值相同的数据元素存放在一个链表中,在查找哈希表的过程中,当查找到这个链表时,必须采用线性查找方法。

 

哈希算法的代价:hash是一种典型以空间换时间的算法,比如原来一个长度为100的数组,对其查找,只需要遍历且匹配相应记录即可,从空间复杂度上来看,假如数组存储的是byte类型数据,那么该数组占用100byte空间。现在我们采用hash算法,我们前面说的hash必须有一个规则,约束键与存储位置的关系,那么就需要一个固定长度的hash表,此时,仍然是100byte的数组,假设我们需要的100byte用来记录键与位置的关系,那么总的空间为200byte,而且用于记录规则的表大小会根据规则,大小可能是不定的。

Hash在Java中的应用:https://www.jianshu.com/p/bf1d7eee28d0第六点

 

全排列、贪心算法、KMP算法

全排列

给定 {1, 2, 3, , , n},其全排列为 n! 个,这是最基础的高中组合数学知识。

https://www.cnblogs.com/nowornever-L/p/6008954.html

 

贪心算法

贪心算法是指:在每一步求解的步骤中,它要求“贪婪”的选择最佳操作,并希望通过一系列的最优选择,能够产生一个问题的(全局的)最优解。

  贪心算法每一步必须满足一下条件:

  1、可行的:即它必须满足问题的约束。

  2、局部最优:他是当前步骤中所有可行选择中最佳的局部选择。

  3、不可取消:即选择一旦做出,在算法的后面步骤就不可改变了。

https://www.cnblogs.com/xsyfl/p/6938642.html

https://www.cnblogs.com/gavanwanggw/p/7141358.html

 

KMP算法

字符串匹配。给你两个字符串,寻找其中一个字符串是否包含另一个字符串,如果包含,返回包含的起始位置。

https://blog.csdn.net/xkx_1223_xkx/article/details/77452658

http://www.cnblogs.com/dusf/p/kmp.html

 

一致性Hash算法

    一致性哈希算法能有效降低服务器个数变化对整体缓存的影响,基本实现原理是将Hash函数的值域空间组织成一个圆环,将服务器节点进行哈希,并将哈希结果映射到圆环上,当有一个写入缓存的请求到来时,使用相同的Hash函数,计算Key的哈希值在圆环上对应的位置,按顺时针方向,将请求定位至离其最近的服务器节点。

https://blog.csdn.net/a19881029/article/details/52766698

https://www.cnblogs.com/lpfuture/p/5796398.html

https://baijiahao.baidu.com/s?id=1577396390971632849&wfr=spider&for=pc

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值