算法笔记 -- 算法思维基础
2021-08-10 10:10:00
#
algorithm
labuladong的算法小抄读书笔记-第一章语言基础
一、C++中的容器
C++的函数参数默认是传值的,如果使用容器作为参数,一般会加上 & 作为传引用。
1.1 动态数组vector
由标准库封装的数组容器,可自动扩容、缩容,int[]声明数组更加高级。
初始化方法:
1 | int n = 7, m =8; |
成员函数
1 | // 返回数组是否为空 |
1.2 字符串string
初始化方法
1 | // s是一个空字符串“” |
成员函数
1 | // 返回字符串的长度 |
1.3 哈希表unordered_map
初始化方法
1 | // 初始化一个key为int,value为int的哈希表 |
成员函数
1 | // 返回哈希表的键值对个数 |
1.4 哈希集合unordered_set
初始化方法
1 | // 初始化一个存储int的哈希集合 |
成员函数
1 | // 返回哈希集合中的键值对个数 |
1.5 队列queue
初始化方法
1 | // 初始化一个存储int的队列 |
成员函数
1 | // 返回队列是否为空 |
C++中一般pop都是void类型,不会在删除的同时将元素返回
1.6 堆栈stack
初始化方法
1 | // 初始化一个存储int的堆栈 |
成员函数
1 | // 返回堆栈是否为空 |
二、Java中容器
Java此处略过,本人对Java相对熟悉,不再赘述
三、Python3中的容器
列表list可以作为数组,可以作为堆栈,也可以作为队列使用:
1 | # 数组 |
元组tuple和字典dict
1 | memo = dict() |
四、算法的框架思维
4.1 存储方式
数据结构的底层存储方式只有两种:数组(顺序存储)和链表(链式存储)
4.2 基本操作
对任何数据结构,操作无非遍历+访问,再具体就是增、删、查、改
各种数据结构的访问+遍历无非两种形式:线性和非线性
线性遍历以for/while为代表,非线性以递归为代表。
数据遍历框架,是典型的线性迭代结构:
1 | void traverse(int[] arr) { |
链表遍历框架,兼具迭代和递归结构:
1 | /*基本的单链表节点*/ |
如在前序遍历处打印head.val就是正序打印链表,在后序遍历处打印head.val就是倒序打印链表
二叉树遍历框架,是典型的非递归遍历结构
1 | /*基本的二叉树节点*/ |
这里可以进一步扩展到N叉树的遍历过程
1 | /*基本的N叉树节点*/ |
4.3 刷题指南
从二叉树开始刷起训练框架思维
Leetcode-124(二叉树中的最大路径和)
Leetcode-105(从前序与中序遍历序列构造二叉树)
Leetcode-99(恢复二叉搜索树)