一份数据结构的快速review

每次面试前我都要重新回顾下题型,找下手感。我觉得基础和经典题型必须会写等等,面试时候沉着应对,一步步思考就可以。
以下内容仅供个人复习参考。

首先是最基本的数据结构:

  1. 数组和字符串(顺序存储)
    涉及两大类问题:
    查找: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++的话就涉及setunordered_setmultisetmapunordered_mapmultimap方法函数的熟练使用。数组本身就可以当作一种哈希表(可用于字符串的情况)。但如果哈希值比较少、特别分散、跨度非常大,使用数组就造成空间的极大浪费,此时可以考虑set或map。

  1. 链表(链式存储)
    包括单链表、双链表、循环链表(可以解决约瑟夫环问题)。
    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 2k1
    完全二叉树指除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 k 层,则该层包含 1 至 2 k − 1 1至 2^{k -1} 12k1 个节点。
    二叉搜索树指若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;它的左、右子树也分别为二叉排序树。
    平衡二叉搜索树又被称为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。
🌲的遍历方式:
深度优先遍历:前序遍历,中序遍历,后序遍历(递归法和迭代法)
广度优先遍历:层序遍历(迭代法)
具体见二叉树的七种遍历
🌲的构造:
前序和中序可以唯一确定一颗二叉树,后序和中序可以唯一确定一颗二叉树,而前序和后序不能唯一确定一颗二叉树!因为没有中序遍历无法确定左右部分,也就是无法分割。
————————————————————————

下面重点说下二叉搜索树是一个有序树:

若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
它的左、右子树也分别为二叉搜索树

对于二叉搜索树比如求最值,求差值等,要利用好其特性——大多是二叉搜索树的题目,其实都离不开中序遍历,因为这样就是有序的。

  • 回溯
result = []
def backtrack(路径, 选择列表):
    if 满足结束条件:
        result.add(路径)
        return
    
    for 选择 in 选择列表:
        做选择
        backtrack(路径, 选择列表)
        撤销选择
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值