牛客选择题整理(一)

1、不稳定排序算法有:快些(希)选对(堆)
2、外部排序过程中,为了减少外存读写次数需要减少归并趟数,可以让初始归并段的长度增减,从而减小初始归并段的段数
3、对于某个元素,如果其后存在一个元素小于它,则称之为存在一个逆序
链接:https://www.nowcoder.com/questionTerminal/4292baed38304e6484bf41bc36522a26 来源:牛客网
下列排序法中,每经过一次元素的交换会产生新的逆序的是(快速排序)
冒泡排序只交换相邻元素,但不是每次移动都产生新的逆序
简单插入排序每一次比较后最多移掉一个逆序
快速排序每一次交换移动都会产生新的逆序,因为当不会有新的逆序产生时,本轮比较结束
简单选择排序的基本思想是先从所有 n 个待排序的数据元素中选择最小的元素,将该元素与第一个元素交换,再从剩下的 n-1 个元素中选出最小的元素与第 2 个元素交换,这样做不会产生逆序
4、只有无冲突的hash table,查找复杂度才是O(1),这是最好的情况。一般是O(c),c为哈希关键字冲突时查找的平均长度
5、流程图G的环形复杂度V(G)=E-N+2
6、长度为N的串,匹配长度为M的子串,时间复杂度为多少
如果问KMP算法的话,那么时间复杂度是O(M+N)
但关键是题目没说是KMP算法呀!所以我理解成“长为N的字符串中匹配长度为M的子串的算法复杂度最快是多少”
那应该是O(M+logN),采用后缀数组匹配


补充:


(1)总串不断移动,直到子串有一个字符,与搜索词(相当于指针)的相同为止,不同的话,搜索词不断后移
(2)执行上一步,直到匹配到与搜索词不同的位置为止
ps传统思路的话:将搜索词整个后移一位,再从头逐个比较
这样做虽然可行,但是效率很差,因为你要把"搜索位置"移到已经比较过的位置,重比一遍
(3)KMP算法的想法是,设法利用这个已知信息,不要把"搜索位置"移回已经比较过的位置,继续把它向后移,这样就提高了效率
(4)具体做法:将子串向后移动,其中移动位数 = 已匹配的字符数 - 对应的部分匹配值
(5)之后子串每次的移动都是按照上述公式移动,不再移动总串,只移动子串
(6)逐位比较,直到搜索词的最后一位,发现完全匹配,于是搜索完成
如果要找出所有的子串,则移动子串长度的位数继续上述过程


子串移动所需的公式中部分匹配值如何求的呢?
部分匹配值"就是"前缀"和"后缀"的最长的共有元素的长度,其中"前缀"指除了最后一个字符以外,一个字符串的全部头部组合;"后缀"指除了第一个字符以外,一个字符串的全部尾部组合。
以"ABCDABD"为例,
"A"的前缀和后缀都为空集,共有元素的长度为0;
"AB"的前缀为[A],后缀为[B],共有元素的长度为0;
"ABC"的前缀为[A, AB],后缀为[BC, C],共有元素的长度0;
"ABCD"的前缀为[A, AB, ABC],后缀为[BCD, CD, D],共有元素的长度为0;
"ABCDA"的前缀为[A, AB, ABC, ABCD],后缀为[BCDA, CDA, DA, A],共有元素为"A",长度为1;
"ABCDAB"的前缀为[A, AB, ABC, ABCD, ABCDA],后缀为[BCDAB, CDAB, DAB, AB, B],共有元素为"AB",长度为2;
"ABCDABD"的前缀为[A, AB, ABC, ABCD, ABCDA, ABCDAB],后缀为[BCDABD, CDABD, DABD, ABD, BD, D],共有元素的长度为0。


关于KMP算法:http://www.ruanyifeng.com/blog/2013/05/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm.html
后缀数组:后缀数组 SA 是一个一维数组
它保存从1到n的某个排列 SA[1 ] ,SA[2] , …… , SA[n]并且保证suffix(SA[i]) < Suffix(SA[i+1]) 1≤ i <n 
也就是将 S 的 n 个后缀从小到大进行排序之后把排好序的后缀的开头位置顺次放入 SA 中。
通俗的讲就是:后缀数组是“排在第几的是谁”,名次数组是“你排第几”
具体到banana这个例子的后缀数组[5, 3, 1, 0, 4, 2],我们可以知道,排在第0位的后缀是从banana第5位开始的后缀a,排在第1位的后缀是从banana第3位开始的后缀ana,排在第2位的后缀是从banana第1位开始的后缀anana,以此类推。
后缀数组的应用:最长公共子串问题的后缀数组解法,参考https://www.byvoid.com/zhs/blog/lcs-suffix-array=


7、求最大k个数的最小时间复杂度
用快排的partition来做的话可以 O(N) 的,用堆的话是O(KlogN),建堆为O(logN),而选择K个就是KlogN
8、以顺序方式存储的线性表,访问第i位置元素的时间复杂性为O(1),因为是用数组保存的,所以访问下标i就可以了



猜你喜欢

转载自blog.csdn.net/FigthingForADream/article/details/80557869