每次面试前我都要重新回顾下题型,找下手感。我觉得基础和经典题型必须会写等等,面试时候沉着应对,一步步思考就可以。
以下内容仅供个人复习参考。
首先是最基本的数据结构:
- 数组和字符串(顺序存储)
涉及两大类问题:
查找:1)顺序查找;2)二分查找;3)哈希查找;
排序:八大基础排序
常用技巧:
双指针法(做题下来,感觉可以分为头尾指针or快慢指针,注意下两者的循环终止条件,理解头或尾,快或慢分别代表什么就可以了)。
滑动窗口(其实是高级点的双指针,可以解决很多子字符串匹配和子数组问题)。其中,滑动窗口的整体思想如下:
int right =0,left =0;
while(right<s.size()){
window.add(s[right]);
right++;
while(valid){
window.remove(s[left]);
left++;
}
}
哈希法,用来快速判断一个元素是否在集合中。
c++的话就涉及set
、unordered_set
和multiset
,map
、unordered_map
和multimap
方法函数的熟练使用。数组本身就可以当作一种哈希表(可用于字符串的情况)。但如果哈希值比较少、特别分散、跨度非常大,使用数组就造成空间的极大浪费,此时可以考虑set或map。
- 链表(链式存储)
包括单链表、双链表、循环链表(可以解决约瑟夫环问题)。
c++版链表定义:
struct ListNode{
int val;
ListNode *next;
ListNode() : val(0), next(nullptr) {}
ListNode(int x) : val(x), next(nullptr) {}
ListNode(int x, ListNode *next) : val(x), next(next) {}
};
python版本链表定义:
class ListNode:
def __init__(self,val=0,next=None):
self.val = val
self.next = next
注意删除头节点的逻辑,可以设置虚拟头节点。
然后是高阶的数据结构:
-
栈和队列
在C++中,stack和queue都是STL中的数据结构。
在Python中,list充当栈,append入栈,pop出栈。from collections import deque
中用deque创建队列,append入队,popleft出队。
其中,栈善于解决匹配类问题。此外还有单调队列,单调栈等特殊数据结构。 -
二叉树
🌲的分类`:
满二叉树指如果一棵二叉树只有度为0的结点和度为2的结点,并且度为0的结点在同一层上,则这棵二叉树为满二叉树。(深度为k,节点数为 2 k − 1 2^k-1 2k−1。
完全二叉树指除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 k 层,则该层包含 1 至 2 k − 1 1至 2^{k -1} 1至2k−1 个节点。
二叉搜索树指若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;它的左、右子树也分别为二叉排序树。
平衡二叉搜索树又被称为AVL(Adelson-Velsky and Landis)树,且具有以下性质:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。
🌲的存储方式:
二叉树可以链式存储,也可以顺序存储。链式存储用指针,顺序存储用数组。顾名思义就是顺序存储的元素在内存是连续分布的,而链式存储则是通过指针把分布在散落在各个地址的节点串联一起。
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
如果父节点的数组下表是i,那么它的左孩子就是i * 2 + 1,右孩子就是 i * 2 + 2。
🌲的遍历方式:
深度优先遍历:前序遍历,中序遍历,后序遍历(递归法和迭代法)
广度优先遍历:层序遍历(迭代法)
具体见二叉树的七种遍历。