精选 100 道基础算法题,筑牢编程与面试根基

100道算法题筑牢编程根基

        算法能力是衡量程序员技术水平的核心指标,无论是应对大厂面试,还是解决实际开发中的复杂问题,扎实的算法基础都必不可少。本文整理了 100 道覆盖各类基础算法的经典题目,按数据结构和算法类型进行系统分类,为你的学习之路提供清晰指引。

        在开始练习前,建议先独立分析问题、动手编码实现,再对照参考答案查漏补缺 —— 这个过程虽具挑战,却是提升算法思维的关键。

一、数组与字符串(20 道)

        数组与字符串作为最基础的数据结构,是算法入门的最佳起点。这类题目着重考察遍历、滑动窗口、双指针等核心技巧,也是后续复杂算法的基石。

  1. 两数之和:在整数数组中寻找和为目标值的两个元素,返回其下标。
  2. 寻找两个正序数组的中位数:要求在 O (log (m+n)) 时间复杂度内,找出两个正序数组的中位数。
  3. 盛最多水的容器:通过数组元素表示垂线高度,寻找能容纳最多水的两条垂线组合。
  4. 三数之和:找出数组中所有和为 0 且不重复的三元组,需注意去重逻辑。
  5. 删除有序数组中的重复项:原地删除升序数组中的重复元素,使每个元素仅出现一次。
  6. 移除元素:原地移除数组中所有值等于目标值的元素,返回新数组长度。
  7. 搜索插入位置:在排序数组中找到目标值的索引,若不存在则返回其应插入的位置。
  8. 最长公共前缀:查找字符串数组中最长的公共前缀,无则返回空字符串。
  9. 有效的括号:判断包含括号的字符串是否符合匹配规则(如 "()[]{}" 有效,"(]" 无效)。
  10. 实现 strStr ():在主字符串中查找子字符串的第一个匹配位置,类似字符串的 indexOf 方法。
  11. 外观数列:从数字 1 开始,后一项是对前一项的描述(如第 3 项为 "21",因前一项是 "11" 即 "两个 1")。
  12. 最大子数组和:寻找连续子数组的最大和,考验对动态规划或分治思想的应用。
  13. 最后一个单词的长度:计算字符串中最后一个单词的长度(单词间由空格分隔)。
  14. 加一:将用数组表示的非负整数加一(如 [1,2,3] 加一后为 [1,2,4])。
  15. 二进制求和:实现两个二进制字符串的加法,返回结果的二进制字符串形式。
  16. x 的平方根:计算非负整数 x 的算术平方根,仅保留整数部分。
  17. 爬楼梯:每次可爬 1 或 2 个台阶,计算到达 n 阶楼顶的不同方法数。
  18. 合并两个有序数组:将两个非递减排序的数组合并为一个有序数组,结果存储在第一个数组中。
  19. 杨辉三角:生成指定行数的杨辉三角,其中每个数是其上方两数之和。
  20. 买卖股票的最佳时机:在给定股票价格数组中,选择一天买入、未来某天卖出,求最大利润。

二、链表(15 道)

        链表通过指针连接节点,与数组的连续内存特性形成鲜明对比,其题目主要考察指针操作和递归思维,是理解复杂数据结构的重要环节。

  1. 删除链表中的节点:仅给定待删除节点(无法访问头节点),实现节点删除操作。
  2. 删除链表的倒数第 N 个结点:高效定位并删除链表的倒数第 n 个节点,可借助快慢指针优化。
  3. 反转链表:将单链表反转(如 1→2→3 变为 3→2→1),考验指针指向的调整逻辑。
  4. 合并两个有序链表:将两个升序链表合并为一个新的升序链表,类似归并排序的合并步骤。
  5. 回文链表:判断单链表是否为回文结构(正向与反向遍历结果一致)。
  6. 环形链表:判断链表中是否存在环,经典解法为快慢指针追及问题。
  7. 环形链表 II:若链表有环,返回环的入口节点;无环则返回 null。
  8. 相交链表:寻找两个单链表的相交起始节点,相交后节点共享同一内存地址。
  9. 移除链表元素:删除链表中所有值等于目标值的节点,返回新的头节点。
  10. 奇偶链表:将链表中索引为奇数的节点放在前半部分,偶数索引节点放在后半部分。
  11. 两数相加:两个非负整数以逆序链表形式存储(如 342 表示为 2→4→3),求两数之和的链表形式。
  12. 旋转链表:将链表每个节点向右移动 k 个位置(如 1→2→3→4→5 移动 2 位后为 4→5→1→2→3)。
  13. 复制带随机指针的链表:对含随机指针的链表进行深拷贝,确保新链表指针独立于原链表。
  14. 排序链表:在 O (n log n) 时间和常数级空间内,将链表按升序排列。
  15. LRU 缓存:设计符合最近最少使用(LRU)策略的缓存结构,支持 get 和 put 操作。

三、栈与队列(10 道)

        栈(LIFO)和队列(FIFO)是两种互补的线性结构,其题目多利用特性解决特定问题,如括号匹配、滑动窗口等,是算法设计的常用工具。

  1. 有效的括号(栈的经典应用,可复用并深化理解)
  2. 最小栈:设计支持 push、pop、top 操作,并能在常数时间内获取最小值的栈。
  3. 用栈实现队列:仅借助两个栈,模拟队列的先进先出(FIFO)特性。
  4. 用队列实现栈:仅借助两个队列,模拟栈的后进先出(LIFO)特性。
  5. 逆波兰表达式求值:计算基于逆波兰表示法的算术表达式(如 ["2","1","+","3","*"] 结果为 9)。
  6. 滑动窗口最大值:在大小为 k 的滑动窗口从数组左端移至右端时,返回每个窗口的最大值。
  7. 每日温度:针对每天的温度,计算下一个更高温度出现的天数,无则为 0。
  8. 下一个更大元素 I:在 nums2 中找到 nums1 各元素右侧第一个更大的元素,nums1 是 nums2 的子集。
  9. 删除字符串中的所有相邻重复项:反复删除字符串中相邻且相同的字母,直至无法删除。
  10. 基本计算器 II:计算包含加减乘除的字符串表达式,整数除法仅保留整数部分。

四、哈希表(10 道)

        哈希表通过键值对存储数据,支持 O (1) 平均时间复杂度的查找、插入和删除,是优化算法效率的重要手段,其题目多涉及去重、计数等场景。

  1. 两数之和(哈希表解法,与数组解法对比,体会时间复杂度优化)
  2. 无重复字符的最长子串:寻找字符串中不含重复字符的最长子串长度。
  3. 字母异位词分组:将由相同字母组成的字符串(字母异位词)归类分组。
  4. 最长连续序列:在未排序数组中,找出数字连续的最长序列长度,要求 O (n) 时间复杂度。
  5. 存在重复元素:判断数组中是否有元素出现至少两次。
  6. 快乐数:判断一个数是否为快乐数(反复替换为各位平方和,最终变为 1 则是)。
  7. 有效的字母异位词:判断两个字符串是否由相同字母组成(长度相同且字母频次一致)。
  8. 赎金信:判断赎金信中的字符能否由杂志中的字符构成(字符可复用但不可超额)。
  9. 四数相加 II:计算四个数组中,满足 nums1 [i] + nums2 [j] + nums3 [k] + nums4 [l] = 0 的元组数量。
  10. 前 K 个高频元素:返回数组中出现频率前 k 高的元素,顺序不限。

五、二叉树(15 道)

        二叉树是树形结构的基础,其题目围绕遍历(前序、中序、后序、层次)、递归和特性应用展开,是理解高级树结构(如 B 树、红黑树)的前提。

  1. 二叉树的中序遍历:返回二叉树的中序(左 - 根 - 右)遍历结果。
  2. 二叉树的最大深度:计算从根节点到最远叶子节点的最长路径上的节点数。
  3. 对称二叉树:判断二叉树是否轴对称(左右子树镜像对称)。
  4. 翻转二叉树:交换二叉树的左右子树,得到原树的镜像。
  5. 路径总和:判断是否存在从根节点到叶子节点的路径,节点值之和等于目标和。
  6. 二叉树的层序遍历:按层次(从上到下、从左到右)返回二叉树的节点值。
  7. 将有序数组转换为二叉搜索树:将升序数组转换为高度平衡的二叉搜索树。
  8. 验证二叉搜索树:判断二叉树是否为有效的二叉搜索树(左子树所有节点值小于根,右子树反之)。
  9. 二叉搜索树中的搜索:在二叉搜索树中查找值等于目标值的节点。
  10. 二叉搜索树中的插入操作:将目标值插入二叉搜索树,保持其特性不变。
  11. 把二叉搜索树转换为累加树:使每个节点的新值等于原树中大于或等于该节点值的所有节点值之和。
  12. 二叉树的最近公共祖先:找到二叉树中两个指定节点的最近公共祖先。
  13. 二叉树展开为链表:将二叉树展开为单链表,展开后节点顺序为原树的前序遍历。
  14. 从前序与中序遍历序列构造二叉树:根据二叉树的前序和中序遍历结果,重建二叉树。
  15. 二叉树的直径:计算二叉树中任意两节点间最长路径的长度(路径上的边数)。

六、排序与搜索(10 道)

        排序和搜索是算法的基础操作,其题目不仅考察经典算法的应用,还涉及对复杂场景的适配(如旋转数组、二维矩阵)。

  1. 合并两个有序数组(复用题目,从排序角度加深理解)
  2. 第一个错误的版本:在版本序列中,找出第一个错误的版本(错误版本后均为错误)。
  3. 在排序数组中查找元素的第一个和最后一个位置:找到目标值在排序数组中的起始和结束索引。
  4. 搜索旋转排序数组:在经一次旋转的排序数组中查找目标值,返回其索引或 - 1。
  5. 寻找峰值:在数组中找到峰值元素(值严格大于左右相邻元素),返回任意一个峰值索引。
  6. 数组中的第 K 个最大元素:返回数组中第 k 个最大的元素(而非第 k 个不同元素)。
  7. 前 K 个高频元素(复用题目,结合排序与哈希表特性)
  8. 颜色分类:原地对包含 0(红)、1(白)、2(蓝)的数组排序,使相同颜色相邻。
  9. 合并区间:将重叠的区间合并,返回不重叠的区间数组(如 [[1,3],[2,6]] 合并为 [[1,6]])。
  10. 搜索二维矩阵 II:在每行、每列均升序的二维矩阵中,高效搜索目标值。

七、动态规划(10 道)

        动态规划通过将复杂问题分解为重叠子问题,利用子问题的解优化计算,是解决最优化问题的重要方法,其核心在于状态定义与转移方程。

  1. 爬楼梯(动态规划入门,对比递归解法理解重叠子问题优化)
  2. 买卖股票的最佳时机 IV:最多完成 k 笔交易,计算能获取的最大利润。
  3. 最大子数组和(动态规划解法,体会状态转移的设计)
  4. 打家劫舍:不能偷窃相邻房屋,计算能偷窃到的最大金额。
  5. 完全平方数:找到和为 n 的完全平方数的最少数量(如 n=12 时,4+4+4 即 3 个)。
  6. 零钱兑换:用给定面额的硬币,凑成总金额所需的最少硬币个数,无法凑成则返回 - 1。
  7. 最长递增子序列:找到数组中最长的严格递增子序列的长度(子序列元素不必连续)。
  8. 单词拆分:判断字符串能否由字典中的单词拼接而成(单词可重复使用)。
  9. 编辑距离:计算将一个单词转换为另一个单词所需的最少操作数(插入、删除、替换)。
  10. 不同的二叉搜索树:计算由 n 个节点组成的不同二叉搜索树的种类数。

八、回溯算法(5 道)

        回溯算法通过试错探索所有可能解,在发现当前路径无效时回退,适用于组合、排列、子集等问题,是暴力搜索的优化形式。

  1. 全排列:返回不含重复数字的数组的所有可能排列。
  2. 子集:返回无重复元素数组的所有可能子集(包括空集和自身)。
  3. 电话号码的字母组合:根据数字 2-9 组成的字符串,返回其对应的所有字母组合(如 "23" 对应 ["ad","ae","af","bd"...])。
  4. 括号生成:生成 n 对所有可能的有效括号组合。
  5. 组合总和:在无重复元素的数组中,找到所有和为目标值的不同组合(元素可重复使用)。

九、数学与位运算(5 道)

        数学与位运算题目考察逻辑思维和对底层运算的理解,常能通过巧妙思路优化算法效率。

  1. Fizz Buzz:对于 1 到 n 的整数,3 的倍数输出 "Fizz",5 的倍数输出 "Buzz",两者都满足则输出 "FizzBuzz"。
  2. 计数质数:计算小于非负整数 n 的质数数量。
  3. 3 的幂:判断一个整数是否为 3 的幂次方。
  4. 位 1 的个数:计算无符号整数二进制表示中 1 的个数(汉明重量)。
  5. 汉明距离:计算两个整数对应二进制位不同的位置数量。

高效学习建议

  1. 阶梯式进阶:从数组、字符串等直观结构入手,再挑战链表、树等复杂结构,最后攻克动态规划、回溯等抽象算法思想。
  2. 深究原理:不仅要写出能运行的代码,更要理解算法的时间 / 空间复杂度、适用场景及优化思路,避免机械记忆。
  3. 定向突破:针对薄弱类型(如动态规划的状态设计),集中练习 5-10 道同类题目,总结通用模板。
  4. 多维度复盘:做完题目后,尝试用不同方法求解(如递归与迭代),对比优劣;隔段时间重新做题,检验是否真正掌握。
  5. 实践中应用:将算法思维迁移到实际项目中,如用哈希表优化查询、用动态规划解决资源分配问题,深化理解。

        算法学习是一个循序渐进、螺旋上升的过程,每道题都是一次思维训练。坚持练习、善于总结,你会逐渐发现算法的内在规律,让代码更高效、更优雅。祝你在算法的世界里不断进步,收获成长!

        欢迎大家在评论区积极回答哦,接下来我会以每天一道题的形式让大家学习算法知识哦。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值