【C++上岸】C++常见面试题目--数据结构篇(第十六期)

大家好!欢迎来到第十六期C++面试题系列,今天我们将深入探讨数据结构相关的经典题目。数据结构是面试中的核心内容,掌握这些不仅能提升你的编程能力,还能让你在面试中脱颖而出。😊本文会逐一讲解每个问题,包括算法思路、C++代码实现,以及一些关键细节。文章结构清晰,确保你一步步理解!每个问题都配有详细代码,让我们开始吧!


文章目录

        • [🔢 1. 斐波那契数列](#🔢 1. 斐波那契数列)
        • [🧱 2. 堆排序](#🧱 2. 堆排序)
        • [🏆 3. 锦标赛排序](#🏆 3. 锦标赛排序)
        • [🇭🇺 4. 匈牙利算法](#🇭🇺 4. 匈牙利算法)
        • [🎒 5. 背包问题](#🎒 5. 背包问题)
        • [🔍 6-8. 数论三连](#🔍 6-8. 数论三连)
        • [⚡ 9. 快速幂](#⚡ 9. 快速幂)
        • [🤖 10. AC自动机](#🤖 10. AC自动机)
      • [💼 面试急救包](#💼 面试急救包)

🔢 1. 斐波那契数列

递归法 (时间复杂度 O ( 2 n ) O(2^n) O(2n),面试慎用!):

cpp 复制代码
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)):

cpp 复制代码
int fib(int n) {
    int a = 0, b = 1;
    while (n--) {
        int c = a + b;
        a = b;
        b = c;
    }
    return a;
}

💡 冷知识 :矩阵快速幂可优化到 O ( log ⁡ n ) O(\log n) O(logn)!


🧱 2. 堆排序

核心思想:构建大顶堆 → 交换堆顶与末尾元素 → 调整堆

cpp 复制代码
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问题:

cpp 复制代码
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实现):

cpp 复制代码
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背包(动态规划):

cpp 复制代码
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];
}

空间优化版(滚动数组):

cpp 复制代码
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. 快速幂

计算 a b m o d    m a^b \mod m abmodm

cpp 复制代码
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思想):

cpp 复制代码
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自动机:一次扫描匹配所有关键词的超级侦探🔍


💼 面试急救包

  1. 手撕代码:堆排序、快速幂必考!
  2. 复杂度分析:务必说清时间/空间复杂度
  3. 边界处理:空输入、负数等 corner case
  4. 优化方向:主动提动态规划空间优化

🎁 🌟如果觉得有用,点个赞吧!👍 收藏本文,面试前翻一翻,上岸更轻松! 如果觉得有用,点赞支持一下,你的鼓励是我持续更新的动力!😊 也欢迎关注我,获取更多"C++上岸"系列干货。下期见!🚀

祝大家offer拿到手软!(๑•̀ㅂ•́)و✧

相关推荐
睡不醒的kun9 小时前
leetcode算法刷题的第二十三天
数据结构·c++·算法·leetcode·职场和发展·贪心算法
mit6.8249 小时前
[re_2] rpc|http|nginx|protobuf|
网络·c++
要做朋鱼燕9 小时前
【C++】 Vector容器操作全解析
开发语言·c++·笔记·学习笔记
北京_宏哥10 小时前
《刚刚问世》系列初窥篇-Java+Playwright自动化测试-38-屏幕截图利器-上篇(详细教程)
java·前端·面试
利刃大大10 小时前
【高并发内存池】三、线程缓存的设计
开发语言·c++·缓存·项目·内存池
Miracle&10 小时前
C++后端开发重点知识点
开发语言·c++
多恩Stone10 小时前
【3D 入门-4】trimesh 极速上手之 3D Mesh 数据结构解析(Vertices / Faces)
数据结构·人工智能·python·3d
1白天的黑夜110 小时前
哈希表-面试题01.02.判定是否互为字符重排-力扣(LeetCode)
c++·leetcode·哈希表
怀旧,10 小时前
【C++】15. ⼆叉搜索树
开发语言·c++