方法:leetcode打基础+剑指Offer针对性训练
数组和字符串是两种最基本的数据结构,它们用连续内存分别存储数字和字符。链表和树是面试中出现频率最高的数据结构。栈是一个与递归紧密相关的数据结构,同样队列也与广度优先遍历算法紧密相关。
大小固定、内存连续、简单哈希表、动态数组
【面试题3】(不修改)找出数组中的重复数字
【面试题4】二维数组中的查找
字符组成、常量字符串、数组字符串
【面试题5】替换空格
基础
提高
子串
回文串
括号
子序列
面试最频繁、代码量适中、空间效率高、环形链表、双向链表、复杂链表
二叉树:前序、中序、后序遍历的递归和迭代写法、层次遍历(宽度优先遍历)、二叉搜索树、堆和红黑树
【面试题7】重建二叉树】
【面试题8】二叉树的下一个节点
遍历基础(递归+迭代)
遍历的应用
二叉搜索树
栈:后进先出,无序
队列:先进先出
【面试题9】用两个栈实现队列
一般算法具有递归和循环两种实现方式,递归简洁但性能不佳;排序和查找是重点,需重点掌握二分查找、归并排序和快速排序;二维数组搜索路径,使用回溯法,适合递归实现;求某个问题最优解,该问题可分为多个子问题,使用动态规划,为避免重复计算,使用自下而上的循环代码实现;分解子问题时存在某个特殊选择,且能得到最优解,适用贪婪算法,并证明贪婪算法能够得到最优解;位运算,包括与、或、异或、左移和右移。
适用于重复计算多次相同的问题,如无特别要求,优先使用递归写法。
递归的本质是将一个问题分解为两个或多个小问题,但是其中很多计算可能都是重复的,对性能带来很大影响。动态规划解决问题是一般用递归思路分析问题,由于递归分解的子问题中存在大量重复,因此我们用自下而上的循环来实现代码。
递归可能导致调用栈溢出。
【面试题10】斐波那契数列
查找:顺序查找、二分查找、哈希表查找和二叉排序树查找。
排序:插入排序、冒泡排序、归并排序、快速排序的特点,从额外空间消耗、平均时间复杂度和最差时间复杂度等方面比较优缺点。
【面试题11】旋转数组的最小数字
=蛮力法“升级版”,适合解决多步骤问题,每个步骤有多个选项,适合递归实现。
将回溯法解决问题的选项用树结构表示,步骤看做为一个节点,选型对应着节点连接线。叶节点不满足约束条件则往上回溯尝试。
【面试题12】矩阵中的路径
【面试题13】机器人的运动范围
动态规划:求一个问题最优解(通常是最大最小值),该问题能够分解成若干个子问题,且子问题之间还有重叠的更小的子问题。 应用动态规划求解问题的特点:
一,求一个问题的最优解;
二,整体问题的最优解依赖各个子问题的最优解;
三,大问题分解成若干小问题,小问题之间有互相重叠的更小的子问题;
四,从上往下分析问题,从下往上求解问题。
贪婪算法:每一步做出一个贪婪的选择,基于这个选择,可以确定能够得到最优解。
【面试题14】剪绳子
位运算:把数字用二进制表示之后,对每一位上0或1的运算。包括与、或、异或、左移和右移五种运算。
左移运算符m<>n表示把m右移n位,右边n位丢弃。
右移无符号数值,用0填充左边n位;右移有符号数,正数用0填充,负数用1填充左边n位。
【面试题15】二进制中1的个数
优点 | 缺点 | |
---|---|---|
返回值 | 和系统API一致 | 不能方便的使用计算结果 |
全局变量 | 能够方便的使用计算结果 | 用户可能会忘记检查全局变量 |
异常 | 可以为不同的出错原因定义不同的异常类型 | 有些语言不支持异常,抛出异常时对性能有负面影响 |
【面试题17】打印从1到最大的n位数
【面试题18】删除链表的节点
【面试题19】正则表达式匹配
【面试题20】表示数值的字符串
【面试题21】调整数组顺序是奇数位于偶数前面
鲁棒性指程序能判断输入是否合乎规范要求,并对不符合要求的输入予以合理的处理。
容错性、防御性编程、
【面试题22】链表中倒数第k个节点
【面试题23】链表中环的入口节点
【面试题24】反转链表
【面试题25】合并两个排序的链表
【面试题26】树的子结构
大多数面试都要求应聘者在白纸或者白板上写代码。应聘者应该在编码的时候注意规范性,尽量清晰的书写每个字母,通过缩进和对其括号让代码布局合理,同时合理命名代码中的变量和函数。
最好在编码之前全面考虑所有可能的输入,确保写出的代码在完成了基本功能之外,还考虑了边界条件,并做好了错误处理。只有全面考虑到这3个方面的代码才是完整的代码。
另外,要确保自己写出的程序不会轻易崩溃。平时在写代码的时候,最好养成防御性编程的习惯,在函数入口判断输入是否有效,并对各种无效输入做好相应的处理。