方法:leetcode打基础+剑指Offer针对性训练
文章目录
【数据结构】
数组和字符串是两种最基本的数据结构,它们用连续内存分别存储数字和字符。链表和树是面试中出现频率最高的数据结构。栈是一个与递归紧密相关的数据结构,同样队列也与广度优先遍历算法紧密相关。
数组✌
大小固定、内存连续、简单哈希表、动态数组
字符串✌
字符组成、常量字符串、数组字符串
基础
提高
子串
回文串
括号
子序列
链表✌
面试最频繁、代码量适中、空间效率高、环形链表、双向链表、复杂链表
- 【206.反转链表】
- 【141.环形链表】
- 【24.两两交换链表中的节点】
- 【328.奇偶链表】
- 【92.反转链表Ⅱ】
- 【237.删除链表中的节点】
- 【19.删除链表的倒数第N个节点】
- 【301.删除无效的括号】
- 【203.移除链表元素】
- 【83.删除排序链表中的重复元素】
- 【82. 删除排序链表中的重复元素 II】
- 【160.相交链表】
- 【21.合并两个有序链表】
- 【143.重排链表】
- 【142.环形链表Ⅱ】
- 【148.排序链表】
- 【25.K个一组翻转链表】
- 【61.旋转链表】
- 【86.分隔链表】
- 【23.合并K个排序链表】
- 【147.对链表进行插入排序】
树✌
二叉树:前序、中序、后序遍历的递归和迭代写法、层次遍历(宽度优先遍历)、二叉搜索树、堆和红黑树
遍历基础(递归+迭代)
遍历的应用
- 【100.相同的树】简单
- 【101.对称二叉树】简单
- 【226.翻转二叉树】
- 【257.二叉树的所有路径】
- 【112.路径总和】
- 【113.路径总和Ⅱ】
- 【124.二叉树中的最大路径和】
- 【129.求根到叶子节点数字之和】
- 【111.二叉树的最小深度】
- 【104.二叉树的最大深度】
- 【110.平衡二叉树】
- 【337.打家劫舍Ⅲ】
- 【107.二叉树的层次遍历Ⅱ】
- 【103.二叉树的锯齿形层次遍历】
- 【199.二叉树的右视图】
二叉搜索树
- 【98.验证二叉搜索树】
- 【235.二叉搜索树的最近公共祖先】
- 【236.二叉树的最近公共祖先】
- 【108.将有序数组转换为二叉搜索树】
- 【109.有序链表转换二叉搜索树】
- 【173.二叉搜索树迭代器】
- 【230.二叉搜索树中第K小的元素】
- 【297.二叉树的序列化和反序列化】
- 【99.恢复二叉搜索树】
- 【116.填充每个节点的下一个右侧节点指针】
- 【117.填充每个节点的下一个右侧节点指针Ⅱ】
- 【96.不同的二叉搜索树】
栈&优先队列✌
栈:后进先出,无序
队列:先进先出
- 【155.最小栈】
- 【232.用栈实现队列】
- 【225.用队列实现栈】
- 【150.逆波兰表达式求值】
- 【71.简化路径】
- 【388.文件的最长绝对路径】
- 【394.字符串解码】
- 【224.基本计算器】
- 【227.基本计算器Ⅱ】
- 【385.迷你语法分析器】
- 【84.柱状图中最大的矩形】
- 【215. 数组中的第K个最大元素】
- 【347.前K个高频元素】
- 【218.天际线问题】
- 【332.重新安排行程】
- 【341.扁平化嵌套列表迭代器】
并查集
字典树
图
矩阵
【算法】
一般算法具有递归和循环两种实现方式,递归简洁但性能不佳;排序和查找是重点,需重点掌握二分查找、归并排序和快速排序;二维数组搜索路径,使用回溯法,适合递归实现;求某个问题最优解,该问题可分为多个子问题,使用动态规划,为避免重复计算,使用自下而上的循环代码实现;分解子问题时存在某个特殊选择,且能得到最优解,适用贪婪算法,并证明贪婪算法能够得到最优解;位运算,包括与、或、异或、左移和右移。
递归和循环
适用于重复计算多次相同的问题,如无特别要求,优先使用递归写法。
递归的本质是将一个问题分解为两个或多个小问题,但是其中很多计算可能都是重复的,对性能带来很大影响。动态规划解决问题是一般用递归思路分析问题,由于递归分解的子问题中存在大量重复,因此我们用自下而上的循环来实现代码。
递归可能导致调用栈溢出。
查找和排序
查找:顺序查找、二分查找、哈希表查找和二叉排序树查找。
排序:插入排序、冒泡排序、归并排序、快速排序的特点,从额外空间消耗、平均时间复杂度和最差时间复杂度等方面比较优缺点。
回溯法
=蛮力法“升级版”,适合解决多步骤问题,每个步骤有多个选项,适合递归实现。
将回溯法解决问题的选项用树结构表示,步骤看做为一个节点,选型对应着节点连接线。叶节点不满足约束条件则往上回溯尝试。
动态规划和贪婪算法
动态规划:求一个问题最优解(通常是最大最小值),该问题能够分解成若干个子问题,且子问题之间还有重叠的更小的子问题。 应用动态规划求解问题的特点:
一,求一个问题的最优解;
二,整体问题的最优解依赖各个子问题的最优解;
三,大问题分解成若干小问题,小问题之间有互相重叠的更小的子问题;
四,从上往下分析问题,从下往上求解问题。
贪婪算法:每一步做出一个贪婪的选择,基于这个选择,可以确定能够得到最优解。
位运算
位运算:把数字用二进制表示之后,对每一位上0或1的运算。包括与、或、异或、左移和右移五种运算。
左移运算符m<<n表示把m左移n位,左边n位丢弃。 右移运算符m>>n表示把m右移n位,右边n位丢弃。
右移无符号数值,用0填充左边n位;右移有符号数,正数用0填充,负数用1填充左边n位。
DFS&BFS
随机
数学
设计
高质量的代码
代码的规范性:清晰的书写、清晰的布局和合理的命名。
代码的完整性:功能测试、边界测试和负面测试。
优点 | 缺点 | |
---|---|---|
返回值 | 和系统API一致 | 不能方便的使用计算结果 |
全局变量 | 能够方便的使用计算结果 | 用户可能会忘记检查全局变量 |
异常 | 可以为不同的出错原因定义不同的异常类型 | 有些语言不支持异常,抛出异常时对性能有负面影响 |
代码的鲁棒性
鲁棒性指程序能判断输入是否合乎规范要求,并对不符合要求的输入予以合理的处理。
容错性、防御性编程、
大多数面试都要求应聘者在白纸或者白板上写代码。应聘者应该在编码的时候注意规范性,尽量清晰的书写每个字母,通过缩进和对其括号让代码布局合理,同时合理命名代码中的变量和函数。
最好在编码之前全面考虑所有可能的输入,确保写出的代码在完成了基本功能之外,还考虑了边界条件,并做好了错误处理。只有全面考虑到这3个方面的代码才是完整的代码。
另外,要确保自己写出的程序不会轻易崩溃。平时在写代码的时候,最好养成防御性编程的习惯,在函数入口判断输入是否有效,并对各种无效输入做好相应的处理。