牛客网专项练习(一)——20道选择题

这次我们来看一些专项练习的题目,总共是20道选择题。

 

分析:因为输入的序列是从小到大的,而输出是从大到小,起泡排序中间不会因为不存在数据交换而提前结束。而是会完全执行所有的比较,也就是最坏的情况。比较次数 5+4+3+2+1=15。

有一个公式就是n*(n-1)/2。

分析:

A、D肯定是错的,不用多说。

B选项.只有一次循环满足某个条件,不调用自己就返回,递归才会一层一层向上返回。

C选项.只陈述了两种情况,还有其他情况也可以使得递归函数结束。1.局部静态变量是可以控制递归函数最终结束的2.可能通过异常来控制递归的结束。3.可以利用BIOS或OS的一些数据或一些标准库的全局值来控制递归过程的终止。4.可以把一些数据写入到BIOS或OS的系统数据区,也可以把数据写入到一个文件中,以此来控制递归函数的终止。

分析:一个递归算法必须包括终止条件和它的递归部分,而于迭代无关。

分析:

分析:分块查找法要求将列表组织成以下索引顺序结构:

首先将列表分成若干个块(子表),一般情况下,块的长度均匀,最后一块可以不满。

每块中元素任意排列,即块内无序,但块与块之间必须有序。

构造一个索引表。其中每个索引项对应一个块并记录每块的起始位置,和每块中最大关键字(或最小关键)。索引表按关键字有序排列。


 分析:答案B

第一次 left=0,right=10,mid=(left+right)/2=5; 索引为5的为55。

第二次 left=mid+1=6 ,right=10; mid=(left+right)/2=8;索引为8的为93。

分析:因为数组元素是基本有序,所以快速排序是最慢的,它会退化成冒泡排序。

选择排序时间复杂度都是O(n^2),堆排序是O(nlogn)。

而基本有序对插入排序是最好的,因为这样只需要比较大小,不需要移动,时间复杂度趋近于O(n)。

分析:说法过于绝对,忽略了对角线上面的元素。

分析:题目要求8行5列地址,其实求的就是A[7][4]地址,故位置为(7*10 + 4)* 4 = 296,即SA+296。

分析:

从(1)到(2):取第一个数25,放到它应该在的位置,25左边的数都比25小,右边的都比25大。

从(2)到(3):对25左边的数列和25右边的数列{20,15,21},{47,27,68,35,84}分别进行快速排序,同样先取各数列的第一个数20和47,使其分别放到应该在的位置,即左边的数都比它小,右边的都比它大。

从(3)到(4):对{15},{21},{35,27},{68,84}四个子序列进行排序,排序完成。

所以从整个过程分析,这是一个快速排序的过程。

具体分析过程:

1:
左指针:49 (不小于49)
右指针:50, 27(不大于49)
交换(49,27)
27,38, 65, 97, 76, 13, 49, 50

2:
左指针:27, 38, 65(不小于49)
右指针:49(不大于49)
交换(65,49)
27,38, 49, 97, 76, 13, 65, 50

3:
左指针:49(不小于49)
右指针:65, 13(不大于49)
交换(49,13)
27,38, 13, 97, 76, 49, 65, 50

4:
左指针:13, 97(不小于49)
右指针:49(不大于49)
交换(97,49)
27,38, 13, 49, 76, 97, 65, 50

5:
左指针:49(不小于49)
右指针:97, 76, 49(不大于49)
左右指针相等,第一趟结束
{27,38, 13} 49 {76, 97, 65, 50}

分析:题目当中没有说S的字串不能为空,所以最后还要再加上一个空串。

字串: n(n+1)/2 + 1

非空子串:n(n+1)/2

非空真子串:n(n+1)/2 - 1

分析:之所以错是因为没有把第一次算进去。

分析:A[ i, j ]在i 行前有 i - 1 行,就有(i - 1) * n 个元素,再加上它是在 j 列,所以就是 (i - 1) * n + j。

分析:j所在的那一列前面有m行,所以j*m,最后再加上前面的i个元素。LOC(a00)+[j*m+i]。

分析:当待排序列已基本有序时,对冒泡排序来说是最好情况,对快速排序来说就是最差情况,而堆排序则最好最差都一样。时间复杂度为O(n)。

分析:线性表采用链表存储时,不要求结点所占空间连续,但是一个结点内部空间必须连续。

分析:

     i       0    1    2    3    4    5    6    7    8

     s      a    b    a    b    a    a    b    a    b

next[i]  -1    0    0    1    2    3    1    2    3

先计算前缀next[i]的值:

next[i]的值主要是看s[i]之前的字符串中重复的子串长度。next[0] = -1,定值。  

next[1]是看s[1]之前的字符串“a”中重复的子串长度为0,故next[1] = 0。

next[2]是看s[2]之前的字符串“ab”中重复的子串长度为0,故next[2] = 0。

next[3]是看s[3]之前的字符串"aba"中重复的子串长度,s[0]与s[2]重复,长度为1,故next[3] = 1。

next[4]是看s[4]之前的字符串"abab"中重复的子串长度,s[01]与s[23]重复,长度为2,故next[4] = 2。

next[5]是看s[5]之前的字符串"ababa"中重复的子串长度,s[012]与s[234]重复,长度为3,故next[5] = 3。

next[6]是看s[6]之前的字符串"ababaa"中重复的子串长度,s[0]与s[5]重复(因为多了一个a,无法找到长度为3的重复字符串这只能是s[0]与s[5]重复),长度为1,故next[6] = 1。

同样的,求next[7]和next[8]分别为2和3。

接下来计算nextval[i]的值:

nextval[i]的求解需要比较s中next[i]所在位置的字符是否与s[i]的字符一致,如果一致则用s[next[i]]的nextval的值作为nextval[i],如果不一致,则用next[i]做为nextval[i]。

nextval[0] = -1,和next[0]的值一样。

nextval[1],比较s[next[1]] ?= s[1],next[1] = 0,s[0] = a,而s[1] = b,二者不一致,则nextval[1] = next[1] = 0。

nextval[2],比较s[next[2]] ?= s[2],next[2] = 0,s[0] = a,而s[2] = a,二者一致,则nextval[2] = nextval[s[next[2]]] = nextval[s[0]] = -1

nextval[3],比较s[next[3]] ?= s[3],next[3] = 1,s[1] = b,而s[3] = b,二者一致,则nextval[3] = nextval[s[next[3]]] = nextval[s[1]] = 0。

nextval[4],比较s[next[4]] ?= s[4],next[4] = 2,s[2] = a,而s[4] = a,二者一致,则nextval[4] = nextval[s[next[4]]] = nextval[s[2]] = -1。

nextval[5],比较s[next[5]] ?= s[5],next[5] = 3,s[3] = b,而s[5] = a,二者不一致,则nextval[5] = next[5] = 3。

同样的求nextval[6],nextval[7],nextval[8]分别为 0 ,-1 , 0。

这里是nextval的下标从-1开始,如果从1开始,则其余各位均+1,nextval为0,1,0,1,0,4,1,0,1。

分析:定义二维数组时,不能省略第二维的大小,这是由编译器原理限制的。所以A错误。C少了一个{

分析:

A.数组在堆上创建。

B.sizeof(数组名)就是数组的容量。

C.const指针不可以。

D. char* str = "hello"; sizeof(str)不能计算出内容的容量,只是指针的容量。

猜你喜欢

转载自blog.csdn.net/Agonyq/article/details/104458162