0.数据结构与算法

4 阅读14分钟

一、 数据结构类面试题

1. 数组 & 字符串

这类问题通常考察对基础数据结构的熟练度和边界处理能力。

  • 经典题目​:

    • 两数之和​:给定一个数组和一个目标值,找出和为目标值的两个数。考点:哈希表的运用。
      • 思路:主要有三种方案,分别是暴力解决,hash表,双指针法(有序数组)
      • 暴力解决:使用两层循环,计算是否有符合num[i] + num[j] = target的值
      • hash表:使用字典的方式对已经遍历过的数据进行num[i] : i的方式进行存储,如果数据可以重复使用,那么就先放入,再判断是否存在 target - num[i] 的值,如果数据不可以重复使用,那么就先判断,再放入
      • 双指针,记录left,right两个指针,计算num[lift] + num[right]与target的关系,如果相等,即可返回,如果值偏小,则将left指针右移,如果值偏大,则将right指针左移,直到两指针相遇
      • 代码示例:java-interview/0-data-structures-and-algorithms/src/main/java/org/interview/TwoNumbersSum.java at main · github2me2/java-interview
    • 移动零​:将数组中的所有 0 移动到末尾,同时保持非零元素的相对顺序。考点:双指针(快慢指针)。
      • 思路:使用快慢指针的方式,分别记录第一个非零的位置和当前遍历的位置; 慢指针记录当前第一个非零的位置的下一个元素,第二个快指针对数组进行遍历,如果当前指针的值是零,向下继续遍历,如果当前指针是非零,则将当前位置与慢指针进行交换;因为如果没有碰上零元素,两个指针会同步向后走,当出现零元素,慢指针不动,快指针继续走,所以慢指针相当于记录到的是第一个零元素的位置,当出现交换的时候,实际是非零与第一个零元素的交换,而如果后面又出现了非零,慢指针则逐渐向后走,直到快指针遍历结束,慢指针始终指向最后一个非零元素的下一个元素
      • 代码示例:java-interview/0-data-structures-and-algorithms/src/main/java/org/interview/MoveZero.java at main · github2me2/java-interview
    • 盛最多水的容器​:给定一个高度数组,找出两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。考点:双指针(对撞指针)。
    • 最长无重复字符子串​:给定一个字符串,请你找出其中不含有重复字符的最长子串的长度。考点:滑动窗口 + 哈希表。
    • 有效的括号​:给定一个只包括 '('')''{''}''['']'的字符串,判断是否有效。考点:栈的应用。
      • 思路:使用栈的先进后出的特点对数据进行匹配,当遇到左括号时,将其压入栈,当遇到右括号时,从栈中弹出元素,如果匹配,则进行下一个,不匹配则返回false,当遍历结束后,如果栈中还有元素,则返回false,如果栈为空,则返回true
      • 拓展问题:只有一种括号,可以简化使用计数器来完成;包含其他字符,需要维护合法括号map,只对合法值进行处理;最长有效括号子串,统计长度,统计数量,获取实际字串等,可以使用栈,动态规划,双指针解决;
      • 代码示例:java-interview/0-data-structures-and-algorithms/src/main/java/org/interview/ValidParentheses.java at main · github2me2/java-interview
    • 二分法查找:给定一个有序数组,要求查找出指定的值

2. 链表

链表问题常考察指针操作、边界情况处理以及是否引入哑节点。

3. 栈 & 队列

考察这两种线性结构的特性和应用场景。

4. 哈希表

考察利用空间换时间的思想。

  • 经典题目​:

    • 两数之和​:(哈希表的经典应用)。
    • 最长无重复字符子串​:(需要哈希表记录字符位置)。
    • 字母异位词分组​:给定一个字符串数组,将字母异位词组合在一起。考点:哈希表的键设计(可以用排序后的字符串或字符计数数组作为键)。

5. 树

二叉树是面试的重中之重,广泛考察递归和遍历。

  • 经典题目​:

    • 二叉树的最大深度​:基础递归题。
    • 二叉树的层序遍历​:广度优先搜索(BFS)的典型应用。
    • 二叉树的最近公共祖先​:求有根树中两个节点的最近公共祖先。考点:递归。
    • 验证二叉搜索树​:判断一个二叉树是否是有效的二叉搜索树(BST)。考点:中序遍历的性质或递归传递上下界。
    • 二叉树的序列化与反序列化​:将二叉树转换成一个字符串,并且能将这个字符串还原成原始的二叉树。考点:各种遍历方式。

6. 堆

常用来解决 Top K 问题。

  • 经典题目​:

    • 数组中的第K个最大元素​:考点:最小堆(维护大小为K的堆)或快速选择算法。
    • 前K个高频元素​:给定一个非空的整数数组,返回其中出现频率前 k 高的元素。考点:哈希表统计频率 + 最小堆。

二、 算法类面试题

1. 排序 & 搜索

考察对基础算法的理解和应用。

  • 经典题目​:

    • 合并两个有序数组​:给定两个有序整数数组 nums1nums2,将 nums2合并到 nums1中,使 nums1成为一个有序数组。考点:逆向双指针。
    • 第一个错误的版本​:假设你有 n 个版本 [1, 2, ..., n],你想找出导致之后所有版本出错的第一个错误的版本。考点:二分查找的变体。

2. 动态规划

面试难点,核心是找到“状态”和“状态转移方程”。

  • 经典题目​:

    • 爬楼梯​:每次你可以爬 1 或 2 个台阶。有多少种不同的方法可以爬到楼顶?最简单的DP入门题。
    • 买卖股票的最佳时机系列:有多种变体(如只能买卖一次、可以买卖多次、含冷冻期等)。考点:状态机DP。
    • 最长递增子序列​:给你一个整数数组,找到其中最长严格递增子序列的长度。考点:经典DP或贪心+二分。
    • 最大子数组和​:给你一个整数数组 nums,请你找出一个具有最大和的连续子数组,返回其最大和。考点:Kadane算法。
    • 编辑距离​:给你两个单词 word1word2,请返回将 word1转换成 word2所使用的最少操作数(插入、删除、替换)。考点:二维DP经典问题。

3. 回溯算法

用于解决排列、组合、分割等问题,本质是暴力穷举的优化(剪枝)。

  • 经典题目​:

    • 全排列​:给定一个不含重复数字的数组 nums,返回其所有可能的全排列。考点:回溯模板。
    • 子集​:给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集。考点:回溯或迭代。
    • 括号生成​:数字 n代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 ​有效的​ 括号组合。考点:回溯 + 剪枝条件(左括号数 < n, 右括号数 < 左括号数)。
    • N 皇后​:经典难题。

4. 贪心算法

在每一步选择中都采取在当前状态下最好或最优的选择。

  • 经典题目​:

    • 买卖股票的最佳时机 II​:你可以尽可能地完成更多的交易(多次买卖一支股票)。考点:贪心(收集所有上坡)。
    • 跳跃游戏​:给定一个非负整数数组 nums,你最初位于数组的第一个下标。数组中的每个元素代表你在该位置可以跳跃的最大长度。判断你是否能够到达最后一个下标。考点:贪心维护最远可达距离。

5. 图

考察图的表示和遍历(BFS/DFS)。

  • 经典题目​:

    • 岛屿数量​:给你一个由 '1'(陆地)和 '0'(水)组成的的二维网格,请你计算网格中岛屿的数量。考点:DFS/BFS 遍历连通分量。
    • 课程表​:你这个学期必须选修 numCourses门课程,记为 0numCourses - 1。在选修某些课程之前需要一些先修课程。判断是否可能完成所有课程的学习?考点:拓扑排序(判断有向图是否有环)。