【C++上岸】C++常见面试题目--数据结构篇(第十六期)
大家好!欢迎来到第十六期C++面试题系列,今天我们将深入探讨数据结构相关的经典题目。数据结构是面试中的核心内容,掌握这些不仅能提升你的编程能力,还能让你在面试中脱颖而出。😊本文会逐一讲解每个问题,包括算法思路、C++代码实现,以及一些关键细节。文章结构清晰,确保你一步步理解!每个问题都配有详细代码,让我们开始吧!
文章目录
- 🔢 1. 斐波那契数列
- 🧱 2. 堆排序
- 🏆 3. 锦标赛排序
- 🇭🇺 4. 匈牙利算法
- 🎒 5. 背包问题
- 🔍 6-8. 数论三连
- ⚡ 9. 快速幂
- 🤖 10. AC自动机
- 💼 面试急救包
🔢 1. 斐波那契数列
递归法(时间复杂度 O(2n)O(2^n)O(2n),面试慎用!):
int fib(int n) {if (n <= 1) return n;return fib(n-1) + fib(n-2);
}
动态规划(时间复杂度 O(n)O(n)O(n),空间 O(1)O(1)O(1)):
int fib(int n) {int a = 0, b = 1;while (n--) {int c = a + b;a = b;b = c;}return a;
}
💡 冷知识:矩阵快速幂可优化到 O(logn)O(\log n)O(logn)!
🧱 2. 堆排序
核心思想:构建大顶堆 → 交换堆顶与末尾元素 → 调整堆
void heapify(int arr[], int n, int i) {int largest = i, l = 2*i+1, r = 2*i+2;if (l < n && arr[l] > arr[largest]) largest = l;if (r < n && arr[r] > arr[largest]) largest = r;if (largest != i) {swap(arr[i], arr[largest]);heapify(arr, n, largest);}
}void heapSort(int arr[], int n) {for (int i = n/2-1; i >= 0; i--) // 建堆heapify(arr, n, i);for (int i = n-1; i > 0; i--) { // 排序swap(arr[0], arr[i]);heapify(arr, i, 0);}
}
堆:当你以为自己是老大,下一秒就被换到最后
🏆 3. 锦标赛排序
树形选择排序,适合找出Top K问题:
vector<int> tournamentSort(vector<int>& arr) {int n = arr.size();vector<int> tree(2*n); // 构建满二叉树for (int i = n; i < 2*n; i++) tree[i] = arr[i-n];// 初始化比赛树for (int i = 2*n-2; i > 0; i -= 2) tree[i/2] = min(tree[i], tree[i+1]);vector<int> res;while (res.size() < n) {res.push_back(tree[1]); // 当前最小值int idx = 1;// 更新树路径while (idx < n) {idx *= 2;if (tree[idx] != tree[1]) idx++;}tree[idx] = INT_MAX; // 标记已选while (idx > 1) { // 向上更新idx /= 2;tree[idx] = min(tree[2*idx], tree[2*idx+1]);}}return res;
}
🇭🇺 4. 匈牙利算法
二分图最大匹配(DFS实现):
bool dfs(int u, vector<vector<int>>& graph, vector<int>& match, vector<bool>& vis) {for (int v : graph[u]) {if (!vis[v]) {vis[v] = true;if (match[v] == -1 || dfs(match[v], graph, match, vis)) {match[v] = u;return true;}}}return false;
}int hungarian(vector<vector<int>>& graph, int n) {vector<int> match(n, -1);int cnt = 0;for (int i = 0; i < n; i++) {vector<bool> vis(n, false);if (dfs(i, graph, match, vis)) cnt++;}return cnt;
}
📌 应用场景:任务分配、约会匹配(没错,就是相亲算法!💘)
🎒 5. 背包问题
经典0-1背包(动态规划):
int knapSack(int W, vector<int>& wt, vector<int>& val) {int n = wt.size();vector<vector<int>> dp(n+1, vector<int>(W+1, 0));for (int i = 1; i <= n; i++) {for (int w = 1; w <= W; w++) {if (wt[i-1] <= w) dp[i][w] = max(val[i-1] + dp[i-1][w-wt[i-1]], dp[i-1][w]);else dp[i][w] = dp[i-1][w];}}return dp[n][W];
}
空间优化版(滚动数组):
int knapSack(int W, vector<int>& wt, vector<int>& val) {vector<int> dp(W+1, 0);for (int i = 0; i < wt.size(); i++)for (int j = W; j >= wt[i]; j--)dp[j] = max(dp[j], val[i] + dp[j - wt[i]]);return dp[W];
}
🔍 6-8. 数论三连
算法 | 代码 | 时间复杂度 |
---|---|---|
最大公约数 | int gcd(int a, int b) { return b ? gcd(b, a % b) : a; } | O(log(min(a,b)))O(\log(\min(a,b)))O(log(min(a,b))) |
最小公倍数 | int lcm(int a, int b) { return a * b / gcd(a, b); } | 同上 |
质数判断 | bool isPrime(int n) { if(n < 2) return false; for(int i=2; i*i<=n; i++) if(n%i==0) return false; return true; } | O(n)O(\sqrt{n})O(n) |
⚡ 9. 快速幂
计算 abmodma^b \mod mabmodm:
long long fastPow(long long a, long long b, long long m) {long long res = 1;a %= m;while (b) {if (b & 1) res = (res * a) % m;a = (a * a) % m;b >>= 1;}return res;
}
🌟 技巧:面试官常考指数取模,记住这个模板!
🤖 10. AC自动机
多模式字符串匹配(Trie树+KMP思想):
struct TrieNode {TrieNode* children[26];TrieNode* fail;bool isEnd;TrieNode() : fail(nullptr), isEnd(false) {memset(children, 0, sizeof(children));}
};void insert(TrieNode* root, string word) {for (char c : word) {int idx = c - 'a';if (!root->children[idx]) root->children[idx] = new TrieNode();root = root->children[idx];}root->isEnd = true;
}void buildAC(TrieNode* root) {queue<TrieNode*> q;q.push(root);while (!q.empty()) {auto node = q.front(); q.pop();for (int i = 0; i < 26; i++) {TrieNode* child = node->children[i];if (!child) continue;if (node == root) child->fail = root;else {TrieNode* f = node->fail;while (f && !f->children[i]) f = f->fail;child->fail = f ? f->children[i] : root;}q.push(child);}}
}bool searchAC(TrieNode* root, string text) {TrieNode* cur = root;for (char c : text) {int idx = c - 'a';while (cur != root && !cur->children[idx]) cur = cur->fail;if (cur->children[idx]) cur = cur->children[idx];if (cur->isEnd) return true; // 匹配到任一模式串}return false;
}
AC自动机:一次扫描匹配所有关键词的超级侦探🔍
💼 面试急救包
- 手撕代码:堆排序、快速幂必考!
- 复杂度分析:务必说清时间/空间复杂度
- 边界处理:空输入、负数等 corner case
- 优化方向:主动提动态规划空间优化
🎁 🌟如果觉得有用,点个赞吧!👍 收藏本文,面试前翻一翻,上岸更轻松! 如果觉得有用,点赞支持一下,你的鼓励是我持续更新的动力!😊 也欢迎关注我,获取更多“C++上岸”系列干货。下期见!🚀
祝大家offer拿到手软!(๑•̀ㅂ•́)و✧