对如下定义的循环单链表,横线处填写( )。
区块链技术是⽐特币的基础。在区块链中,每个区块指向前⼀个区块,构成链式列表,新区块只能接在链尾,不允许在中间插⼊或删除。下⾯代码实现插⼊区块添加函数,则横线处填写( )。
Block* newBlock = new Block(tail->index + 1, data, tail);tail = newBlock->prev;
Block* newBlock = new Block(tail->index + 1, data, tail);tail = newBlock;
Block* newBlock = new Block(tail->index + 1, data, tail->prev);tail = newBlock;
Block* newBlock = new Block(tail->index + 1, data, tail->prev);tail = newBlock->prev;
下⾯关于单链表和双链表的描述中,正确的是( )。
双链表删除指定节点是 O(1),单链表是O(1)
双链表删除指定节点是O(n) ,单链表是O(1)
双链表删除指定节点是O(1) ,单链表是O(n)
双链表删除指定节点是 O(n),单链表是O(n)
假设我们有两个数a=38 和b=14 ,它们对模 m同余,即a≡b(mod m) 。以下哪个值不可能是m ?
3
4
6
9
下⾯代码实现了欧⼏⾥得算法。下⾯有关说法,错误的是( )。
gcd1() 实现为递归⽅式。
gcd2() 实现为迭代⽅式。
当 较⼤时,gcd1() 实现会多次调⽤⾃⾝,需要较多额外的辅助空间。
当 较⼤时,gcd1() 的实现⽐ gcd2() 执⾏效率更⾼。
唯⼀分解定理描述的内容是( )。
任何正整数都可以表⽰为两个素数的和。
任何⼤于1的合数都可以唯⼀分解为有限个质数的乘积。
两个正整数的最⼤公约数总是等于它们的最⼩公倍数除以它们的乘积。
所有素数都是奇数。
下述代码实现素数表的线性筛法,筛选出所有⼩于等于 的素数,则横线上应填的代码是( )。
for (int j = 0; j < primes.size() && i * primes[j] <= n; j++)
for(int j = sqrt(n); j <= n && i * primes[j] <= n; j++)
for (int j = 1; j <= sqrt(n); j++)
for(int j = 1; j < n && i * primes[j] <= n; j++)
下列关于排序的说法,正确的是( )。
快速排序是稳定排序
归并排序通常是稳定的
插⼊排序是不稳定排序
冒泡排序不是原地排序
下⾯代码实现了归并排序。下述关于归并排序的说法中,不正确的是( )。
归并排序的平均复杂度是O(nlogn) 。
归并排序需要O(n) 的额外空间。
归并排序在最坏情况的时间复杂度是O(n2) 。
归并排序适合⼤规模数据。
下述C++代码实现了快速排序算法,最坏情况的时间复杂度是( )。
O(n)
O(logn)
O(n2)
O(nlogn)
下⾯代码尝试在有序数组中查找第⼀个⼤于等于 x 的元素位置。如果没有⼤于等于 x 的元素,返回arr.size()。以下说法正确的是( )。
上述代码逻辑正确
上述代码逻辑错误,while 循环条件应该⽤ l <= r
上述代码逻辑错误,mid 计算错误
上述代码逻辑错误,边界条件不对
⼩杨要把⼀根长度为 L 的⽊头切成 K 段,使得每段长度⼩于等于 x。已知每切⼀⼑只能把⼀段⽊头分成两段,他⽤⼆分法找到满⾜条件的最⼩ x(x 为正整数),则横线处应填写( )。
if (check(L, K, mid))r = mid;elsel = mid + 1;
if (check(L, K, mid))r = mid+1;elsel = mid + 1;
if (check(L, K, mid))r = mid + 1;elsel = mid - 1;
if (check(L, K, mid))r = mid + 1;elsel = mid;
下⾯给出了阶乘计算的两种⽅式。以下说法正确的是( )。
上⾯两种实现⽅式的时间复杂度相同,都为O(n)
上⾯两种实现⽅式的空间复杂度相同,都为O(n)
上⾯两种实现⽅式的空间复杂度相同,都为O(1)
函数 factorial1() 的时间复杂度为 O(2n),函数 factorial2() 的时间复杂度为O(n)
给定有n个任务,每个任务有截⽌时间和利润,每个任务耗时 1 个时间单位、必须在截⽌时间前完成,且每个时间槽最多做 1 个任务。为了在规定时间内获得最⼤利润,可以采⽤贪⼼策略,即按利润从⾼到低排序,尽量安排,则横线处应填写( )。
slot[t] = true;totalProfit += task.profit;
slot[t] = false;totalProfit += task.profit;
slot[t] = true;totalProfit = task.profit;
slot[t] = false;totalProfit = task.profit;
下⾯代码实现了对两个数组表⽰的正整数的⾼精度加法(数组低位在前),则横线上应填写( )。
c.push_back(carry / 10);carry %= 10;
c.push_back(carry % 10);carry /= 10;
c.push_back(carry % 10);
c.push_back(carry);carry /= 10;
数组和链表都是线性表。链表的优点是插⼊删除不需要移动元素,并且能随机查找。
假设函数 gcd() 函数能正确求两个正整数的最⼤公约数,则下⾯的 lcm(a,b) 函数能正确找到两个正整数 a 和 b 的最⼩公倍数。
在单链表中,已知指针 p 指向要删除的结点(⾮尾结点),想在 删除 p,可⾏做法是⽤ p->next覆盖 p 的值与 next,然后删除 p->next。
在求解所有不⼤于 n 的素数时,线性筛法(欧拉筛)都应当优先于埃⽒筛法使⽤,因为线性筛法的时间复杂度为O(n) ,低于埃⽒筛法的O(nloglogn) 。
⼆分查找仅适⽤于有序数据。若输⼊数据⽆序,当仅进⾏⼀次查找时,为了使⽤⼆分⽽排序通常不划算。
通过在数组的第⼀个、最中间和最后⼀个这3个数据中选择中间值作为枢轴(⽐较基准),快速排序算法可降低落⼊最坏情况的概率。
贪⼼算法在每⼀步都做出当前看来最优的局部选择,并且⼀旦做出选择就不再回溯;⽽分治算法将问题分解为若⼲⼦问题分别求解,再将⼦问题的解合并得到原问题的解。
以下 fib 函数计算第 n 项斐波那契数(fib(0)=0, fib(1)=1),其时间复杂度为 O(n)。
递归函数⼀定要有终⽌条件,否则可能会造成栈溢出。
使⽤贪⼼算法解决问题时,通过对每⼀步求局部最优解,最终⼀定能找到全局最优解。