Skip to content

算法与数据结构 共13题

题目清单

  • M15:关于哈希表正确的有?
  • M16:关于堆正确的有?
  • M17:关于二分正确的有?
  • M18:关于递归 DFS 正确的有?
  • F01:补全 lower_bound。
  • F02:补全链表反转。
  • F03:补全快速幂。
  • F06:补全 BFS 队列。
  • F08:补全 KMP 失配跳转。
  • F09:补全堆下沉孩子下标。
  • F10:补全前缀和区间查询。
  • F13:补全拓扑排序入度更新。
  • F14:补全滑动窗口无重复。

不定项选择题

M15. 不定项选择题

关于哈希表正确的有?

A. 平均 O(1) 依赖分布和负载 B. 冲突可链地址解决 C. 最坏可能退化 D. 一定保持 key 有序

答案:A、B、C

解析:哈希表不保证顺序。

题目图示

M16. 不定项选择题

关于堆正确的有?

A. priority_queue 默认大顶堆 B. 可用于 TopK C. 插入 O(log n) D. 查找任意元素 O(1)

答案:A、B、C

解析:堆只能快速访问堆顶,不能 O(1) 查任意元素。

题目图示

M17. 不定项选择题

关于二分正确的有?

A. 要求答案或谓词有单调性 B. 可用于 sqrt C. 边界容易错 D. 不需要循环终止条件

答案:A、B、C

解析:二分核心是单调性和边界设计。

题目图示

M18. 不定项选择题

关于递归 DFS 正确的有?

A. 可能栈溢出 B. 适合树/图遍历 C. 需要 visited 防重复 D. 永远比 BFS 快

答案:A、B、C

解析:DFS/BFS 取决于问题,没有永远更快。

题目图示

代码填空

F01. 代码填空

补全 lower_bound。

cpp
int lowerBound(vector<int>& a, int x) {
    int l=0, r=a.size();
    while (l<r) {
        int m=l+(r-l)/2;
        if (/*1*/) {
            l=/*2*/;
        }
        else {
            r=/*3*/;
        }
    }
    return l;
}

答案:

cpp
a[m] < x
m + 1
m

解析:第一个 >= x,mid 小于目标时丢弃左侧。

题目图示

F02. 代码填空

补全链表反转。

cpp
ListNode* rev(ListNode* h) {
    ListNode* pre=nullptr;
    while (h) {
        ListNode* nxt=/*1*/;
        h->next=/*2*/;
        pre=/*3*/;
        h=nxt;
    }
    return pre;
}

答案:

cpp
h->next
pre
h

解析:先保存 next,再改指针,否则后续链表丢失。

题目图示

F03. 代码填空

补全快速幂。

cpp
long long qpow(long long a, long long n, long long mod) {
    long long ans=1%mod;
    while (n) {
        if (/*1*/) {
            ans=/*2*/;
        }
        a=/*3*/;
        n>>=1;
    }
    return ans;
}

答案:

cpp
n & 1
ans * a % mod
a * a % mod

解析:指数按二进制拆,低位为 1 就乘入答案。

题目图示

F06. 代码填空

补全 BFS 队列。

cpp
int bfs(vector<vector<int>>& g, int s) {
    queue<int> q;
    vector<int> vis(g.size());
    q.push(s);
    vis[s]=1;
    int cnt=0;
    while (!q.empty()) {
        int u=q.front();
        /*1*/;
        cnt++;
        for (int v:g[u]) {
            if (!vis[v]) {
                /*2*/;
                q.push(v);
            }
        }
    }
    return cnt;
}

答案:

cpp
q.pop()
vis[v] = 1

解析:BFS 出队后访问邻居,入队时立刻标记避免重复入队。

题目图示

F08. 代码填空

补全 KMP 失配跳转。

cpp
while (j>0 && s[i]!=p[j])
    j = /*1*/;

答案:

cpp
nxt[j - 1]

解析:KMP 失配后跳到上一个最长相等前后缀长度。

题目图示

F09. 代码填空

补全堆下沉孩子下标。

cpp
int l = i * 2 + /*1*/;
int r = i * 2 + /*2*/;

答案:

cpp
1
2

解析:数组堆中下标 i 的左右孩子是 2i+1、2i+2。

题目图示

F10. 代码填空

补全前缀和区间查询。

cpp
sum(l, r)= prefix[/*1*/] - prefix[/*2*/];
// prefix[0]=0, 区间闭区间 [l, r]

答案:

cpp
r + 1
l

解析:前缀和 prefix[i] 表示前 i 个元素之和。

题目图示

F13. 代码填空

补全拓扑排序入度更新。

cpp
for (int v:g[u]) {
    if (--indeg[v] == /*1*/) {
        q.push(v);
    }
}

答案:

cpp
0

解析:入度变为 0 表示所有前置已处理,可以入队。

题目图示

F14. 代码填空

补全滑动窗口无重复。

cpp
if (last.count(c) {
    ) left=max(left, /*1*/);
}
last[c]=right;

答案:

cpp
last[c] + 1

解析:重复字符在窗口内时,左边界移动到上次位置后一格。

题目图示

文章评价

读完这篇,留下你的看法

暂无审核通过的评价。

登录账号后才能评价。

本站访客数0总站访问量0本页访问量0