当前位置: 首页 > web >正文

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

大家好!😊 欢迎来到“C++上岸”系列的第19期——算法篇!算法是面试中的硬核关卡,掌握好这些经典问题,能让你在笔试和面试中游刃有余。今天,我们精选了10道高频算法题,涵盖双指针等核心思想。我会逐一详细解答,包括算法思路和C++代码实现。🔥准备好了吗?让我们开始吧!


1. 移动零

要求:原地将数组中的零移到末尾,保持非零元素顺序。
思路:双指针法。指针left标记非零元素位置,遍历数组,遇到非零元素就交换到left处。

void moveZeroes(vector<int>& nums) {for (int left = 0, i = 0; i < nums.size(); i++) {if (nums[i] != 0) swap(nums[left++], nums[i]);}
}

时间复杂度O(n)O(n)O(n)空间复杂度O(1)O(1)O(1)
(假装有图)


2. 比较含退格的字符串

要求#代表退格,判断两字符串是否相等。
思路:重构字符串(模拟栈)。遇到非#入栈,遇到#出栈。

bool backspaceCompare(string s, string t) {return build(s) == build(t);
}
string build(string str) {string res;for (char c : str) {if (c == '#') { if (!res.empty()) res.pop_back(); }else res.push_back(c);}return res;
}

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


3. 有序数组的平方

要求:非递减数组平方后仍非递减。
思路:双指针从两端向中间遍历,比较平方值。

vector<int> sortedSquares(vector<int>& nums) {int left = 0, right = nums.size() - 1;vector<int> res(nums.size());for (int i = nums.size() - 1; i >= 0; i--) {if (abs(nums[left]) > abs(nums[right])) {res[i] = nums[left] * nums[left];left++;} else {res[i] = nums[right] * nums[right];right--;}}return res;
}

时间复杂度O(n)O(n)O(n)


4. 长度最小的子数组

要求:和≥s的最短连续子数组长度。
思路:滑动窗口。右指针扩张,左指针收缩。

int minSubArrayLen(int target, vector<int>& nums) {int left = 0, sum = 0, minLen = INT_MAX;for (int right = 0; right < nums.size(); right++) {sum += nums[right];while (sum >= target) {minLen = min(minLen, right - left + 1);sum -= nums[left++];}}return minLen == INT_MAX ? 0 : minLen;
}

时间复杂度O(n)O(n)O(n)


5. 水果成篮

要求:最多收集两种水果的最大连续数量。
思路:滑动窗口+哈希表记录水果类型数。

int totalFruit(vector<int>& fruits) {unordered_map<int, int> basket;int left = 0, maxFruits = 0;for (int right = 0; right < fruits.size(); right++) {basket[fruits[right]]++;while (basket.size() > 2) {if (--basket[fruits[left]] == 0) basket.erase(fruits[left]);left++;}maxFruits = max(maxFruits, right - left + 1);}return maxFruits;
}

时间复杂度O(n)O(n)O(n)


6. 最小覆盖子串

要求:s中包含t所有字符的最短子串。
思路:滑动窗口+双哈希表(需求窗口+当前窗口)。

string minWindow(string s, string t) {unordered_map<char, int> need, window;for (char c : t) need[c]++;int left = 0, valid = 0, start = 0, minLen = INT_MAX;for (int right = 0; right < s.size(); right++) {char c = s[right];if (need.count(c)) {window[c]++;if (window[c] == need[c]) valid++;}while (valid == need.size()) {if (right - left < minLen) {minLen = right - left;start = left;}char d = s[left++];if (need.count(d)) {if (window[d] == need[d]) valid--;window[d]--;}}}return minLen == INT_MAX ? "" : s.substr(start, minLen);
}

时间复杂度O(n)O(n)O(n)


7. 螺旋矩阵 II

要求:生成顺时针螺旋的 n×nn \times nn×n 矩阵。
思路:模拟螺旋路径,控制边界。

vector<vector<int>> generateMatrix(int n) {vector<vector<int>> matrix(n, vector<int>(n));int top = 0, bottom = n - 1, left = 0, right = n - 1;int num = 1;while (num <= n * n) {for (int i = left; i <= right; i++) matrix[top][i] = num++;top++;for (int i = top; i <= bottom; i++) matrix[i][right] = num++;right--;for (int i = right; i >= left; i--) matrix[bottom][i] = num++;bottom--;for (int i = bottom; i >= top; i--) matrix[i][left] = num++;left++;}return matrix;
}

示例n=3[[1,2,3],[8,9,4],[7,6,5]]


8. 螺旋遍历二维数组

要求:返回二维数组的螺旋遍历结果。
思路:同问题7,按层模拟方向。

vector<int> spiralOrder(vector<vector<int>>& matrix) {if (matrix.empty()) return {};int m = matrix.size(), n = matrix[0].size();int top = 0, bottom = m - 1, left = 0, right = n - 1;vector<int> res;while (res.size() < m * n) {for (int i = left; i <= right; i++) res.push_back(matrix[top][i]);top++;for (int i = top; i <= bottom; i++) res.push_back(matrix[i][right]);right--;if (top <= bottom) {for (int i = right; i >= left; i--) res.push_back(matrix[bottom][i]);bottom--;}if (left <= right) {for (int i = bottom; i >= top; i--) res.push_back(matrix[i][left]);left++;}}return res;
}

9. 区间求和

要求:多次查询数组区间和。
思路:前缀和预处理。

int main() {int n;cin >> n;vector<int> nums(n), prefix(n + 1, 0);for (int i = 0; i < n; i++) {cin >> nums[i];prefix[i + 1] = prefix[i] + nums[i];}int l, r;while (cin >> l >> r) {cout << prefix[r + 1] - prefix[l] << endl; // [l, r]区间和}
}

时间复杂度:查询 O(1)O(1)O(1),预处理 O(n)O(n)O(n)


10. 土地价值最小差

要求:横向或纵向切割网格,使两区域价值和差最小。
思路:枚举切割线 + 前缀和优化。

int minDifference(vector<vector<int>>& grid) {int n = grid.size(), m = grid[0].size();// 计算行前缀和vector<vector<int>> rowSum(n, vector<int>(m + 1, 0));for (int i = 0; i < n; i++) for (int j = 0; j < m; j++) rowSum[i][j + 1] = rowSum[i][j] + grid[i][j];int total = 0, minDiff = INT_MAX;for (auto& row : grid) for (int val : row) total += val;// 枚举横向切割for (int i = 1; i < n; i++) {int sumTop = 0;for (int k = 0; k < i; k++) sumTop += rowSum[k][m];minDiff = min(minDiff, abs(2 * sumTop - total));}// 枚举纵向切割(类似)// ...return minDiff;
}

关键点:预处理行列前缀和,减少重复计算。


总结

本期涵盖了双指针滑动窗口前缀和螺旋矩阵四大核心考点。面试前背熟这些代码,通过率+50%!💯
彩蛋:遇到“水果成篮”这类题,心里默念:“滑动窗口,yyds!” 🍉🍇

恭喜你坚持到了最后!🎉 本期我们覆盖了10道经典算法题,包括双指针等核心思想。掌握这些,能让你在C++面试中脱颖而出。算法学习重在实践,建议多写代码和模拟测试。如果你有疑问或想讨论,欢迎留言!😊 下期见,继续“C++上岸”之旅!🔥

http://www.xdnf.cn/news/20185.html

相关文章:

  • 2025年8月文章一览
  • 深度学习:自定义数据集处理、数据增强与最优模型管理
  • 数据旁路(Data Bypassing)是什么?
  • 安装3DS MAX 2026后,无法运行,提示缺少.net core的解决方案
  • 2025年数学建模国赛C题第二版本超详细解题思路
  • Qwen-agent 核心功能分析学习
  • 从零开始学无监督学习:图像混合与标签平滑技术详解,收藏不走丢
  • C++开发中的常用设计模式:深入解析与应用场景
  • javaweb基础第一天总结(HTML-CSS)
  • SpringBoot中 Gzip 压缩的两种开启方式:GeoJSON 瘦身实战
  • 基于网络原理——HTTP/HTTPS的Web服务搭建与核心技术实践
  • Ubuntu 使用 Samba 共享文件夹
  • 什么是CA根证书
  • Apache PDFBox 与 spire.pdf for java 使用记录
  • 软件架构师全方位工具图谱
  • Java全栈开发面试实战:从基础到高并发的深度解析
  • 【数学建模学习笔记】机器学习回归:决策树回归
  • 无人机信号防干扰技术难点分析
  • 企业白名单实现【使用拦截器】
  • 梯度爆炸问题:深度学习中的「链式核弹」与拆弹指南
  • 嵌入式学习 51单片机(3)
  • (自用)cmd常用命令自查文档
  • 大语言模型基础-Transformer之上下文
  • (计算机网络)TCP 粘包与拆包
  • STM32传感器模块编程实践(十五)DIY语音对话控制+满溢检测智能垃圾桶模型
  • Selenium 超时完全指南:pageLoadTimeout、implicitlyWait 和 scriptTimeout 的深度解析
  • NineData发布 Oracle 到 MySQL 双向实时复制,助力去 O 战略与数据回流
  • 小迪安全v2023学习笔记(七十七讲)—— 业务设计篇隐私合规检测重定向漏洞资源拒绝服务
  • ⸢ 肆 ⸥ ⤳ 默认安全建设方案:b.安全资产建设
  • 【C++】16. set和map