【C++上岸】C++常见面试题目--算法篇(第二十期)

还在为算法面试发愁?别怕!本文精选10道C++高频算法题,手把手教你解题思路+代码实现,助你轻松上岸!🚀


文章目录

      • [1. 字母异位词判断 🔤](#1. 字母异位词判断 🔤)
      • [2. 两数之和 🎯](#2. 两数之和 🎯)
      • [3. 快乐数 😄](#3. 快乐数 😄)
      • [4. 赎金信 ✉️](#4. 赎金信 ✉️)
      • [5. 三数之和 🌟](#5. 三数之和 🌟)
      • [6. 四数之和 🔢](#6. 四数之和 🔢)
      • [7. 四数相加II 🧮](#7. 四数相加II 🧮)
      • [8. 有效的数独 ✅](#8. 有效的数独 ✅)
      • [9. LRU缓存机制 ⚙️](#9. LRU缓存机制 ⚙️)
      • [总结 🎉](#总结 🎉)

1. 字母异位词判断 🔤

题目 :判断字符串 t 是否是 s 的字母异位词(字母相同但顺序不同)。
示例

输入:s = "anagram", t = "nagaram" → 输出:true

解法

  • 核心:统计字符频次是否一致。
  • 步骤
    1. 若长度不等,直接返回 false
    2. 用数组 freq[26] 统计 s 的字符频次;
    3. 遍历 t,减少频次,若出现负数则无效。

C++代码

cpp 复制代码
bool isAnagram(string s, string t) {
    if (s.size() != t.size()) return false;
    int freq[26] = {0};
    for (char c : s) freq[c - 'a']++;
    for (char c : t) if (--freq[c - 'a'] < 0) return false;
    return true;
}

时间复杂度 : O ( n ) O(n) O(n),空间复杂度: O ( 1 ) O(1) O(1)(固定大小数组)


2. 两数之和 🎯

题目 :在数组 nums 中找出和为 target 的两个数,返回其下标。
要求:每种输入只对应一个答案,且元素不重复使用。

解法

  • 核心:哈希表记录遍历过的值及其下标。
  • 步骤
    1. 遍历数组,计算补数 complement = target - nums[i]
    2. 若补数在哈希表中,返回下标;否则记录当前值。

C++代码

cpp 复制代码
vector<int> twoSum(vector<int>& nums, int target) {
    unordered_map<int, int> map;
    for (int i = 0; i < nums.size(); i++) {
        int comp = target - nums[i];
        if (map.count(comp)) return {map[comp], i};
        map[nums[i]] = i;
    }
    return {};
}

时间复杂度 : O ( n ) O(n) O(n),空间复杂度: O ( n ) O(n) O(n)


3. 快乐数 😄

题目 :判断一个数 n 是否为快乐数(最终通过平方和变为1)。
关键点:若陷入循环则不是快乐数。

解法

  • 核心:用哈希集合检测循环。
  • 步骤
    1. 计算 n 的各位平方和;
    2. 若和为 1,返回 true
    3. 若和已存在于集合,返回 false;否则加入集合并继续。

C++代码

cpp 复制代码
bool isHappy(int n) {
    unordered_set<int> seen;
    while (n != 1) {
        int sum = 0;
        while (n) {
            int digit = n % 10;
            sum += digit * digit;
            n /= 10;
        }
        if (seen.count(sum)) return false;
        seen.insert(sum);
        n = sum;
    }
    return true;
}

时间复杂度 : O ( log ⁡ n ) O(\log n) O(logn)(收敛速度快),空间复杂度: O ( log ⁡ n ) O(\log n) O(logn)


4. 赎金信 ✉️

题目 :判断 ransom 能否由 magazine 中的字符构成(每个字符仅用一次)。

解法

  • 核心 :统计 magazine 的字符频次,检查是否覆盖 ransom
  • 步骤
    1. 用数组统计 magazine 的字符频次;
    2. 遍历 ransom,减少频次,若出现负数则无效。

C++代码

cpp 复制代码
bool canConstruct(string ransom, string magazine) {
    int freq[26] = {0};
    for (char c : magazine) freq[c - 'a']++;
    for (char c : ransom) if (--freq[c - 'a'] < 0) return false;
    return true;
}

时间复杂度 : O ( m + n ) O(m+n) O(m+n),空间复杂度: O ( 1 ) O(1) O(1)


5. 三数之和 🌟

题目 :找出数组 nums 中所有和为 0 的不重复三元组。

解法

  • 核心:排序 + 双指针。
  • 步骤
    1. 排序数组;
    2. 遍历数组,对每个元素 nums[i],用双指针在右侧找 -nums[i]
    3. 跳过重复元素避免重复解。

C++代码

cpp 复制代码
vector<vector<int>> threeSum(vector<int>& nums) {
    sort(nums.begin(), nums.end());
    vector<vector<int>> res;
    for (int i = 0; i < nums.size(); i++) {
        if (i > 0 && nums[i] == nums[i-1]) continue; // 去重
        int left = i + 1, right = nums.size() - 1;
        while (left < right) {
            int sum = nums[i] + nums[left] + nums[right];
            if (sum == 0) {
                res.push_back({nums[i], nums[left], nums[right]});
                while (left < right && nums[left] == nums[left+1]) left++; // 去重
                while (left < right && nums[right] == nums[right-1]) right--; // 去重
                left++; right--;
            } 
            else if (sum < 0) left++;
            else right--;
        }
    }
    return res;
}

时间复杂度 : O ( n 2 ) O(n^2) O(n2),空间复杂度: O ( 1 ) O(1) O(1)(忽略输出存储)


6. 四数之和 🔢

题目 :找出数组 nums 中所有和为 target 的不重复四元组。

解法

  • 核心:排序 + 双层循环 + 双指针(类似三数之和)。
  • 步骤
    1. 排序数组;
    2. 两层循环确定前两个数,双指针确定后两个数;
    3. 跳过重复元素。

C++代码

cpp 复制代码
vector<vector<int>> fourSum(vector<int>& nums, int target) {
    sort(nums.begin(), nums.end());
    vector<vector<int>> res;
    for (int i = 0; i < nums.size(); i++) {
        if (i > 0 && nums[i] == nums[i-1]) continue;
        for (int j = i + 1; j < nums.size(); j++) {
            if (j > i+1 && nums[j] == nums[j-1]) continue;
            int left = j + 1, right = nums.size() - 1;
            while (left < right) {
                long sum = (long)nums[i] + nums[j] + nums[left] + nums[right];
                if (sum == target) {
                    res.push_back({nums[i], nums[j], nums[left], nums[right]});
                    while (left < right && nums[left] == nums[left+1]) left++;
                    while (left < right && nums[right] == nums[right-1]) right--;
                    left++; right--;
                } 
                else if (sum < target) left++;
                else right--;
            }
        }
    }
    return res;
}

时间复杂度 : O ( n 3 ) O(n^3) O(n3)


7. 四数相加II 🧮

题目 :计算四个等长数组 A, B, C, D 中,有多少元组满足 A [ i ] + B [ j ] + C [ k ] + D [ l ] = 0 A[i] + B[j] + C[k] + D[l] = 0 A[i]+B[j]+C[k]+D[l]=0。

解法

  • 核心:分组 + 哈希表。
  • 步骤
    1. 计算 AB 所有元素和,存入哈希表(和→频次);
    2. 计算 CD 所有元素和,查找哈希表中是否存在相反数。

C++代码

cpp 复制代码
int fourSumCount(vector<int>& A, vector<int>& B, vector<int>& C, vector<int>& D) {
    unordered_map<int, int> map;
    for (int a : A) for (int b : B) map[a + b]++;
    int count = 0;
    for (int c : C) for (int d : D) count += map[-(c + d)];
    return count;
}

时间复杂度 : O ( n 2 ) O(n^2) O(n2),空间复杂度: O ( n 2 ) O(n^2) O(n2)


8. 有效的数独 ✅

题目:判断 9×9 数独是否有效(行、列、3×3宫内无重复数字)。

解法

  • 核心:用三个二维数组分别记录行、列、宫内的数字出现情况。
  • 关键 :宫索引计算:box_index = (i / 3) * 3 + j / 3

C++代码

cpp 复制代码
bool isValidSudoku(vector<vector<char>>& board) {
    int rows[9][9] = {0}, cols[9][9] = {0}, boxes[9][9] = {0};
    for (int i = 0; i < 9; i++) {
        for (int j = 0; j < 9; j++) {
            if (board[i][j] == '.') continue;
            int num = board[i][j] - '1';
            int box_idx = (i / 3) * 3 + j / 3;
            if (rows[i][num] || cols[j][num] || boxes[box_idx][num]) 
                return false;
            rows[i][num] = cols[j][num] = boxes[box_idx][num] = 1;
        }
    }
    return true;
}

时间复杂度 : O ( 1 ) O(1) O(1)(固定81次循环),空间复杂度: O ( 1 ) O(1) O(1)


9. LRU缓存机制 ⚙️

题目 :设计 LRU 缓存,支持 getput 操作(时间复杂度 O ( 1 ) O(1) O(1))。

解法

  • 核心:双向链表(维护使用顺序) + 哈希表(快速定位节点)。
  • 关键操作
    • get:将节点移到链表头部;
    • put:若存在则更新值并移到头部;若不存在则插入新节点,若超容则删除尾部节点。

C++代码

cpp 复制代码
class LRUCache {
private:
    struct Node {
        int key, val;
        Node *prev, *next;
        Node(int k, int v) : key(k), val(v) {}
    };
    unordered_map<int, Node*> map;
    Node *head, *tail;
    int capacity;
    
    void removeNode(Node* node) {
        node->prev->next = node->next;
        node->next->prev = node->prev;
    }
    
    void addToHead(Node* node) {
        node->next = head->next;
        node->prev = head;
        head->next->prev = node;
        head->next = node;
    }
    
    void moveToHead(Node* node) {
        removeNode(node);
        addToHead(node);
    }
    
    Node* popTail() {
        Node* node = tail->prev;
        removeNode(node);
        return node;
    }

public:
    LRUCache(int cap) : capacity(cap) {
        head = new Node(-1, -1);
        tail = new Node(-1, -1);
        head->next = tail;
        tail->prev = head;
    }
    
    int get(int key) {
        if (!map.count(key)) return -1;
        Node* node = map[key];
        moveToHead(node);
        return node->val;
    }
    
    void put(int key, int value) {
        if (map.count(key)) {
            Node* node = map[key];
            node->val = value;
            moveToHead(node);
        } else {
            Node* node = new Node(key, value);
            map[key] = node;
            addToHead(node);
            if (map.size() > capacity) {
                Node* tail = popTail();
                map.erase(tail->key);
                delete tail;
            }
        }
    }
};

时间复杂度 : O ( 1 ) O(1) O(1) 所有操作


总结 🎉

掌握这10道题,算法面试不再慌!重点在于:

  • 哈希表用于快速查找(两数之和、字母异位词等);
  • 双指针用于有序数组的搜索(三数之和等);
  • 链表+哈希实现 O ( 1 ) O(1) O(1) 复杂度的 LRU。
    快去刷题吧,offer在等你!💪

如果本文对你有帮助,欢迎点赞收藏🌟

需要完整代码模板的评论区留言~👇

相关推荐
JJJJ_iii4 小时前
【左程云算法03】对数器&算法和数据结构大致分类
数据结构·算法·分类
轮到我狗叫了4 小时前
牛客.小红的子串牛客.kotori和抽卡牛客.循环汉诺塔牛客.ruby和薯条
java·开发语言·算法
高山有多高4 小时前
详解文件操作
c语言·开发语言·数据库·c++·算法
乌萨奇也要立志学C++4 小时前
【洛谷】队列相关经典算法题详解:模板队列、机器翻译、海港
算法
狂奔的sherry5 小时前
单例模式(巨通俗易懂)普通单例,懒汉单例的实现和区别,依赖注入......
开发语言·c++·单例模式
YuTaoShao5 小时前
【LeetCode 热题 100】49. 字母异位词分组
算法·leetcode·哈希算法
EnigmaCoder5 小时前
【C++】引用的本质与高效应用
开发语言·c++
郭涤生6 小时前
arma::imat22
c++
aliedudu6 小时前
决策树概念与原理
算法·决策树·机器学习