|
|
|
|
算法和数据结构体系学习班
|
|
|
|
|
|
|
|
|
|
00 算法和数据结构学前必看
|
|
|
|
|
|
|
|
|
|
内容:
|
|
|
|
|
|
|
|
|
|
算法和数据结构课程体系介绍
|
|
|
|
|
|
|
|
|
|
算法和数据结构学习路线
|
|
|
|
|
|
|
|
|
|
算法和数据结构学习方式推荐
|
|
|
|
|
|
|
|
|
|
算法和数据结构面试软技巧
|
|
|
|
|
|
|
|
|
|
同学们的各种答疑问题
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
01 时间复杂度、空间复杂度、对数器和二分法
|
|
|
|
|
|
|
|
|
|
内容:
|
|
|
|
|
|
|
|
|
|
评估算法优劣的核心指标
|
|
|
|
|
|
|
|
|
|
时间复杂度、空间复杂度、估算方式、意义
|
|
|
|
|
|
|
|
|
|
常数时间的操作
|
|
|
|
|
|
|
|
|
|
选择排序、冒泡排序、插入排序
|
|
|
|
|
|
|
|
|
|
最优解
|
|
|
|
|
|
|
|
|
|
对数器
|
|
|
|
|
|
|
|
|
|
二分法
|
|
|
|
|
|
|
|
|
|
题目:
|
|
|
|
|
|
|
|
|
|
选择排序及其对数器验证
|
|
|
|
|
|
|
|
|
|
冒泡排序及其对数器验证
|
|
|
|
|
|
|
|
|
|
插入排序及其对数器验证
|
|
|
|
|
|
|
|
|
|
有序数组中找到num
|
|
|
|
|
|
|
|
|
|
有序数组中找到>=num最左的位置
|
|
|
|
|
|
|
|
|
|
有序数组中找到<=num最右的位置
|
|
|
|
|
|
|
|
|
|
局部最小值问题
|
|
|
|
|
定义何为局部最小值:
|
|
|
|
|
arr[0] < arr[1],0位置是局部最小;
|
|
|
|
|
arr[N-1] < arr[N-2],N-1位置是局部最小;
|
|
|
|
|
arr[i-1] > arr[i] < arr[i+1],i位置是局部最小;
|
|
|
|
|
给定一个数组arr,已知任何两个相邻的数都不相等,找到随便一个局部最小位置返回
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
02 异或运算、进一步认识对数器的重要性
|
|
|
|
|
|
|
|
|
|
内容:
|
|
|
|
|
|
|
|
|
|
异或运算的性质
|
|
|
|
|
|
|
|
|
|
异或运算的题目
|
|
|
|
|
|
|
|
|
|
题目:
|
|
|
|
|
|
|
|
|
|
不用额外变量交换两个数的值
|
|
|
|
|
|
|
|
|
|
不用额外变量交换数组中两个数的值
|
|
|
|
|
|
|
|
|
|
一个数组中有一种数出现了奇数次,其他数都出现了偶数次,怎么找到并打印这种数
|
|
|
|
|
|
|
|
|
|
怎么把一个int类型的数,提取出二进制中最右侧的1来
|
|
|
|
|
|
|
|
|
|
一个数组中有两种数出现了奇数次,其他数都出现了偶数次,怎么找到并打印这两种数
|
|
|
|
|
|
|
|
|
|
一个数组中有一种数出现K次,其他数都出现了M次,
|
|
|
|
|
已知M > 1,K < M,找到出现了K次的数
|
|
|
|
|
要求额外空间复杂度O(1),时间复杂度O(N)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
03 单双链表、栈和队列、递归和Master公式、哈希表和有序表的使用和性能
|
|
|
|
|
|
|
|
|
|
内容:
|
|
|
|
|
|
|
|
|
|
单链表、双链表
|
|
|
|
|
|
|
|
|
|
栈、队列
|
|
|
|
|
|
|
|
|
|
递归的物理实质
|
|
|
|
|
|
|
|
|
|
评估递归复杂度的Master公式
|
|
|
|
|
|
|
|
|
|
哈希表的使用和性能
|
|
|
|
|
|
|
|
|
|
有序表的使用和性能
|
|
|
|
|
|
|
|
|
|
题目:
|
|
|
|
|
|
|
|
|
|
反转单链表、反转双链表
|
|
|
|
|
|
|
|
|
|
在链表中删除指定值的所有节点
|
|
|
|
|
|
|
|
|
|
用双链表实现栈和队列
|
|
|
|
|
|
|
|
|
|
用环形数组实现栈和队列
|
|
|
|
|
|
|
|
|
|
实现有getMin功能的栈
|
|
|
|
|
|
|
|
|
|
两个栈实现队列
|
|
|
|
|
|
|
|
|
|
两个队列实现栈
|
|
|
|
|
|
|
|
|
|
用递归行为得到数组中的最大值,并用master公式来估计时间复杂度
|
|
|
|
|
|
|
|
|
|
哈希表和有序表使用的code展示
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
04 归并排序及其常见面试题
|
|
|
|
|
|
|
|
|
|
内容:
|
|
|
|
|
|
|
|
|
|
归并排序
|
|
|
|
|
|
|
|
|
|
题目:
|
|
|
|
|
|
|
|
|
|
归并排序的递归和非递归实现
|
|
|
|
|
|
|
|
|
|
在一个数组中,一个数左边比它小的数的总和,叫该数的小和
|
|
|
|
|
所有数的小和累加起来,叫数组小和
|
|
|
|
|
例子: [1,3,4,2,5]
|
|
|
|
|
1左边比1小的数:没有
|
|
|
|
|
3左边比3小的数:1
|
|
|
|
|
4左边比4小的数:1、3
|
|
|
|
|
2左边比2小的数:1
|
|
|
|
|
5左边比5小的数:1、3、4、 2
|
|
|
|
|
所以数组的小和为1+1+3+1+1+3+4+2=16
|
|
|
|
|
给定一个数组arr,求数组小和
|
|
|
|
|
|
|
|
|
|
在一个数组中,任何一个前面的数a,和任何一个后面的数b,如果(a,b)是降序的,就称为降序对
|
|
|
|
|
给定一个数组arr,求数组的降序对总数量
|
|
|
|
|
|
|
|
|
|
在一个数组中,对于任何一个数num,求有多少个(后面的数*2)依然<num,返回总个数
|
|
|
|
|
比如:[3,1,7,0,2]
|
|
|
|
|
3的后面有:1,0
|
|
|
|
|
1的后面有:0
|
|
|
|
|
7的后面有:0,2
|
|
|
|
|
0的后面没有
|
|
|
|
|
2的后面没有
|
|
|
|
|
所以总共有5个
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
05 归并排序面试题(续)、快速排序
|
|
|
|
|
|
|
|
|
|
内容:
|
|
|
|
|
|
|
|
|
|
再来一个归并排序面试题
|
|
|
|
|
|
|
|
|
|
荷兰国旗问题
|
|
|
|
|
|
|
|
|
|
快速排序1.0
|
|
|
|
|
|
|
|
|
|
快速排序2.0
|
|
|
|
|
|
|
|
|
|
快速排序3.0
|
|
|
|
|
|
|
|
|
|
题目:
|
|
|
|
|
|
|
|
|
|
给定一个数组arr,两个整数lower和upper,
|
|
|
|
|
返回arr中有多少个子数组的累加和在[lower,upper]范围上
|
|
|
|
|
Leetcode题目:https://leetcode.com/problems/count-of-range-sum/
|
|
|
|
|
|
|
|
|
|
荷兰国旗问题的实现
|
|
|
|
|
|
|
|
|
|
快速排序从1.0到3.0的实现
|
|
|
|
|
|
|
|
|
|
快速排序的递归实现和非递归实现
|
|
|
|
|
|
|
|
|
|
code附加,双向链表进行快速排序的code实现
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
06 比较器、堆结构、堆排序
|
|
|
|
|
|
|
|
|
|
内容:
|
|
|
|
|
|
|
|
|
|
比较器
|
|
|
|
|
|
|
|
|
|
堆结构
|
|
|
|
|
|
|
|
|
|
堆排序
|
|
|
|
|
|
|
|
|
|
建立大根堆的两种方式,从上到下、从下到上,及其复杂度分析
|
|
|
|
|
|
|
|
|
|
题目:
|
|
|
|
|
|
|
|
|
|
比较器使用的code展示
|
|
|
|
|
|
|
|
|
|
堆结构的实现
|
|
|
|
|
|
|
|
|
|
堆排序的实现
|
|
|
|
|
|
|
|
|
|
已知一个几乎有序的数组。几乎有序是指,如果把数组排好顺序的话,每个元素移动的距离一定不超过k
|
|
|
|
|
k相对于数组长度来说是比较小的。请选择一个合适的排序策略,对这个数组进行排序。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
07 和堆有关的面试题、加强堆结构
|
|
|
|
|
|
|
|
|
|
内容:
|
|
|
|
|
|
|
|
|
|
线段最大重合问题
|
|
|
|
|
|
|
|
|
|
加强堆的实现
|
|
|
|
|
|
|
|
|
|
题目:
|
|
|
|
|
|
|
|
|
|
给定很多线段,每个线段都有两个数[start, end],
|
|
|
|
|
表示线段开始位置和结束位置,左右都是闭区间
|
|
|
|
|
规定:
|
|
|
|
|
1)线段的开始和结束位置一定都是整数值
|
|
|
|
|
2)线段重合区域的长度必须>=1
|
|
|
|
|
返回线段最多重合区域中,包含了几条线段
|
|
|
|
|
|
|
|
|
|
加强堆的实现、注意点解析
|
|
|
|
|
|
|
|
|
|
做一个加强堆的题目,给定一个整型数组,int[] arr;和一个布尔类型数组,boolean[] op
|
|
|
|
|
两个数组一定等长,假设长度为N,arr[i]表示客户编号,op[i]表示客户操作
|
|
|
|
|
arr= [3,3,1,2,1,2,5…
|
|
|
|
|
op = [T,T,T,T,F,T,F…
|
|
|
|
|
依次表示:
|
|
|
|
|
3用户购买了一件商品
|
|
|
|
|
3用户购买了一件商品
|
|
|
|
|
1用户购买了一件商品
|
|
|
|
|
2用户购买了一件商品
|
|
|
|
|
1用户退货了一件商品
|
|
|
|
|
2用户购买了一件商品
|
|
|
|
|
5用户退货了一件商品…
|
|
|
|
|
一对arr[i]和op[i]就代表一个事件:
|
|
|
|
|
用户号为arr[i],op[i] == T就代表这个用户购买了一件商品
|
|
|
|
|
op[i] == F就代表这个用户退货了一件商品
|
|
|
|
|
现在你作为电商平台负责人,你想在每一个事件到来的时候,
|
|
|
|
|
都给购买次数最多的前K名用户颁奖。
|
|
|
|
|
所以每个事件发生后,你都需要一个得奖名单(得奖区)。
|
|
|
|
|
得奖系统的规则:
|
|
|
|
|
1,如果某个用户购买商品数为0,但是又发生了退货事件,
|
|
|
|
|
则认为该事件无效,得奖名单和上一个事件发生后一致,例子中的5用户
|
|
|
|
|
2,某用户发生购买商品事件,购买商品数+1,发生退货事件,购买商品数-1
|
|
|
|
|
3,每次都是最多K个用户得奖,K也为传入的参数
|
|
|
|
|
如果根据全部规则,得奖人数确实不够K个,那就以不够的情况输出结果
|
|
|
|
|
4,得奖系统分为得奖区和候选区,任何用户只要购买数>0,
|
|
|
|
|
一定在这两个区域中的一个
|
|
|
|
|
5,购买数最大的前K名用户进入得奖区,
|
|
|
|
|
在最初时如果得奖区没有到达K个用户,那么新来的用户直接进入得奖区
|
|
|
|
|
6,如果购买数不足以进入得奖区的用户,进入候选区
|
|
|
|
|
7,如果候选区购买数最多的用户,已经足以进入得奖区,
|
|
|
|
|
该用户就会替换得奖区中购买数最少的用户(大于才能替换),
|
|
|
|
|
如果得奖区中购买数最少的用户有多个,就替换最早进入得奖区的用户
|
|
|
|
|
如果候选区中购买数最多的用户有多个,机会会给最早进入候选区的用户
|
|
|
|
|
8,候选区和得奖区是两套时间,
|
|
|
|
|
因用户只会在其中一个区域,所以只会有一个区域的时间,另一个没有
|
|
|
|
|
从得奖区出来进入候选区的用户,得奖区时间删除,
|
|
|
|
|
进入候选区的时间就是当前事件的时间(可以理解为arr[i]和op[i]中的i)
|
|
|
|
|
从候选区出来进入得奖区的用户,候选区时间删除,
|
|
|
|
|
进入得奖区的时间就是当前事件的时间(可以理解为arr[i]和op[i]中的i)
|
|
|
|
|
9,如果某用户购买数==0,不管在哪个区域都离开,区域时间删除,
|
|
|
|
|
离开是指彻底离开,哪个区域也不会找到该用户
|
|
|
|
|
如果下次该用户又发生购买行为,产生>0的购买数,
|
|
|
|
|
会再次根据之前规则回到某个区域中,进入区域的时间重记
|
|
|
|
|
请遍历arr数组和op数组,遍历每一步输出一个得奖名单
|
|
|
|
|
public List<List<Integer>> topK (int[] arr, boolean[] op, int k)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
08 前缀树、不基于比较的排序(计数排序、基数排序)、排序算法的稳定性
|
|
|
|
|
|
|
|
|
|
内容:
|
|
|
|
|
|
|
|
|
|
前缀树
|
|
|
|
|
|
|
|
|
|
计数排序
|
|
|
|
|
|
|
|
|
|
基数排序
|
|
|
|
|
|
|
|
|
|
排序算法的稳定性
|
|
|
|
|
|
|
|
|
|
题目:
|
|
|
|
|
|
|
|
|
|
前缀树实现
|
|
|
|
|
|
|
|
|
|
计数排序
|
|
|
|
|
|
|
|
|
|
基数排序
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
09 排序算法大总结、链表及其相关面试题
|
|
|
|
|
|
|
|
|
|
内容:
|
|
|
|
|
|
|
|
|
|
排序算法总结
|
|
|
|
|
|
|
|
|
|
排序算法常见的坑
|
|
|
|
|
|
|
|
|
|
工程上对排序的常见改进
|
|
|
|
|
|
|
|
|
|
链表面试题的常见技巧
|
|
|
|
|
|
|
|
|
|
题目:
|
|
|
|
|
|
|
|
|
|
输入链表头节点,奇数长度返回中点,偶数长度返回上中点
|
|
|
|
|
输入链表头节点,奇数长度返回中点,偶数长度返回下中点
|
|
|
|
|
输入链表头节点,奇数长度返回中点前一个,偶数长度返回上中点前一个
|
|
|
|
|
输入链表头节点,奇数长度返回中点前一个,偶数长度返回下中点前一个
|
|
|
|
|
|
|
|
|
|
给定一个单链表的头节点head,请判断该链表是否为回文结构
|
|
|
|
|
|
|
|
|
|
给定一个单链表的头节点head,给定一个整数n,将链表按n划分成左边<n、中间==n、右边>n
|
|
|
|
|
|
|
|
|
|
一种特殊的单链表节点类描述如下
|
|
|
|
|
class Node {
|
|
|
|
|
int value;
|
|
|
|
|
Node next;
|
|
|
|
|
Node rand;
|
|
|
|
|
Node(int val) { value = val; }
|
|
|
|
|
}
|
|
|
|
|
rand指针是单链表节点结构中新增的指针,rand可能指向链表中的任意一个节点,也可能指向null
|
|
|
|
|
给定一个由Node节点类型组成的无环单链表的头节点head,请实现一个函数完成这个链表的复制
|
|
|
|
|
返回复制的新链表的头节点,要求时间复杂度O(N),额外空间复杂度O(1)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
10 链表相关面试题(续)、二叉树的常见遍历
|
|
|
|
|
|
|
|
|
|
内容:
|
|
|
|
|
|
|
|
|
|
单链表的相交节点系列问题
|
|
|
|
|
|
|
|
|
|
一种看似高效其实搞笑的节点删除方式
|
|
|
|
|
|
|
|
|
|
二叉树的中序、先序、后序遍历
|
|
|
|
|
|
|
|
|
|
题目:
|
|
|
|
|
|
|
|
|
|
给定两个可能有环也可能无环的单链表,头节点head1和head2
|
|
|
|
|
请实现一个函数,如果两个链表相交,请返回相交的第一个节点。如果不相交返回null
|
|
|
|
|
要求如果两个链表长度之和为N,时间复杂度请达到O(N),额外空间复杂度请达到O(1)
|
|
|
|
|
|
|
|
|
|
能不能不给单链表的头节点,只给想要删除的节点,就能做到在链表上把这个点删掉?
|
|
|
|
|
|
|
|
|
|
二叉树先序、中序、后序的递归遍历和递归序
|
|
|
|
|
|
|
|
|
|
二叉树先序、中序、后序的非递归遍历
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
11 二叉树常见面试题和二叉树的递归套路(上)
|
|
|
|
|
|
|
|
|
|
内容:
|
|
|
|
|
|
|
|
|
|
通过题目来熟悉二叉树的解题技巧
|
|
|
|
|
|
|
|
|
|
题目:
|
|
|
|
|
|
|
|
|
|
二叉树的按层遍历
|
|
|
|
|
|
|
|
|
|
二叉树的序列化和反序列化
|
|
|
|
|
|
|
|
|
|
N叉树如何通过二叉树来序列化、并完成反序列化
|
|
|
|
|
Leetcode题目:https://leetcode.com/problems/encode-n-ary-tree-to-binary-tree/
|
|
|
|
|
|
|
|
|
|
打印二叉树的函数设计
|
|
|
|
|
|
|
|
|
|
求二叉树的最大宽度
|
|
|
|
|
|
|
|
|
|
求二叉树某个节点的后继节点
|
|
|
|
|
二叉树结构如下定义:
|
|
|
|
|
Class Node {
|
|
|
|
|
V value;
|
|
|
|
|
Node left;
|
|
|
|
|
Node right;
|
|
|
|
|
Node parent;
|
|
|
|
|
}
|
|
|
|
|
给你二叉树中的某个节点,返回该节点的后继节点
|
|
|
|
|
|
|
|
|
|
折纸问题
|
|
|
|
|
请把一段纸条竖着放在桌子上,然后从纸条的下边向上方对折1次,压出折痕后展开
|
|
|
|
|
此时折痕是凹下去的,即折痕突起的方向指向纸条的背面
|
|
|
|
|
如果从纸条的下边向上方连续对折2次,压出折痕后展开
|
|
|
|
|
此时有三条折痕,从上到下依次是下折痕、下折痕和上折痕。
|
|
|
|
|
给定一个输入参数N,代表纸条都从下边向上方连续对折N次
|
|
|
|
|
请从上到下打印所有折痕的方向。
|
|
|
|
|
N=1时,打印: down
|
|
|
|
|
N=2时,打印: down down up
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
12 二叉树常见面试题和二叉树的递归套路(中)
|
|
|
|
|
|
|
|
|
|
内容:
|
|
|
|
|
|
|
|
|
|
通过题目来熟悉二叉树的解题技巧
|
|
|
|
|
|
|
|
|
|
介绍二叉树的递归套路
|
|
|
|
|
1)假设以X节点为头,假设可以向X左树和X右树要任何信息
|
|
|
|
|
2)在上一步的假设下,讨论以X为头节点的树,得到答案的可能性(最重要)
|
|
|
|
|
3)列出所有可能性后,确定到底需要向左树和右树要什么样的信息
|
|
|
|
|
4)把左树信息和右树信息求全集,就是任何一棵子树都需要返回的信息S
|
|
|
|
|
5)递归函数都返回S,每一棵子树都这么要求
|
|
|
|
|
6)写代码,在代码中考虑如何把左树的信息和右树信息整合出整棵树的信息
|
|
|
|
|
|
|
|
|
|
题目:
|
|
|
|
|
|
|
|
|
|
判断二叉树是不是搜索二叉树
|
|
|
|
|
|
|
|
|
|
判断二叉树是不是平衡二叉树
|
|
|
|
|
|
|
|
|
|
判断二叉树是不是满二叉树
|
|
|
|
|
|
|
|
|
|
给定一棵二叉树的头节点head,返回这颗二叉树中最大的二叉搜索子树的大小
|
|
|
|
|
|
|
|
|
|
给定一棵二叉树的头节点head,任何两个节点之间都存在距离,返回整棵二叉树的最大距离
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
13 二叉树常见面试题和二叉树的递归套路(下)、贪心算法
|
|
|
|
|
|
|
|
|
|
内容:
|
|
|
|
|
|
|
|
|
|
二叉树递归套路继续实践
|
|
|
|
|
|
|
|
|
|
一道贪心算法从头到尾的完整做法
|
|
|
|
|
|
|
|
|
|
解决贪心题目的重要技巧,即对数器来验证脑洞
|
|
|
|
|
|
|
|
|
|
再次强调对数器的重要性
|
|
|
|
|
|
|
|
|
|
题目:
|
|
|
|
|
|
|
|
|
|
判断二叉树是不是完全二叉树(一般方法解决、递归套路解决)
|
|
|
|
|
|
|
|
|
|
给定一棵二叉树的头节点head,返回这颗二叉树中最大的二叉搜索子树的头节点
|
|
|
|
|
|
|
|
|
|
给定一棵二叉树的头节点head,和另外两个节点a和b,返回a和b的最低公共祖先
|
|
|
|
|
|
|
|
|
|
派对的最大快乐值
|
|
|
|
|
员工信息的定义如下:
|
|
|
|
|
class Employee {
|
|
|
|
|
public int happy; // 这名员工可以带来的快乐值
|
|
|
|
|
List<Employee> subordinates; // 这名员工有哪些直接下级
|
|
|
|
|
}
|
|
|
|
|
公司的每个员工都符合 Employee 类的描述。整个公司的人员结构可以看作是一棵标准的、 没有环的多叉树
|
|
|
|
|
树的头节点是公司唯一的老板,除老板之外的每个员工都有唯一的直接上级
|
|
|
|
|
叶节点是没有任何下属的基层员工(subordinates列表为空),除基层员工外每个员工都有一个或多个直接下级
|
|
|
|
|
这个公司现在要办party,你可以决定哪些员工来,哪些员工不来,规则:
|
|
|
|
|
1.如果某个员工来了,那么这个员工的所有直接下级都不能来
|
|
|
|
|
2.派对的整体快乐值是所有到场员工快乐值的累加
|
|
|
|
|
3.你的目标是让派对的整体快乐值尽量大
|
|
|
|
|
给定一棵多叉树的头节点boss,请返回派对的最大快乐值。
|
|
|
|
|
|
|
|
|
|
给定一个由字符串组成的数组strs,必须把所有的字符串拼接起来,返回所有可能的拼接结果中字典序最小的结果
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
14 贪心算法(续)、并查集
|
|
|
|
|
|
|
|
|
|
内容:
|
|
|
|
|
|
|
|
|
|
贪心算法继续实战
|
|
|
|
|
|
|
|
|
|
并查集详解
|
|
|
|
|
|
|
|
|
|
题目:
|
|
|
|
|
|
|
|
|
|
给定一个字符串str,只由'X'和'.'两种字符构成
|
|
|
|
|
'X'表示墙,不能放灯,也不需要点亮;'.'表示居民点,可以放灯,需要点亮
|
|
|
|
|
如果灯放在i位置,可以让i-1,i和i+1三个位置被点亮
|
|
|
|
|
返回如果点亮str中所有需要点亮的位置,至少需要几盏灯
|
|
|
|
|
|
|
|
|
|
一块金条切成两半,是需要花费和长度数值一样的铜板
|
|
|
|
|
比如长度为20的金条,不管怎么切都要花费20个铜板,一群人想整分整块金条,怎么分最省铜板?
|
|
|
|
|
例如,给定数组{10,20,30},代表一共三个人,整块金条长度为60,金条要分成10,20,30三个部分。
|
|
|
|
|
如果先把长度60的金条分成10和50,花费60;再把长度50的金条分成20和30,花费50;一共花费110铜板
|
|
|
|
|
但如果先把长度60的金条分成30和30,花费60;再把长度30金条分成10和20,花费30;一共花费90铜板
|
|
|
|
|
输入一个数组,返回分割的最小代价
|
|
|
|
|
|
|
|
|
|
一些项目要占用一个会议室宣讲,会议室不能同时容纳两个项目的宣讲,给你每一个项目开始的时间和结束的时间
|
|
|
|
|
你来安排宣讲的日程,要求会议室进行的宣讲的场次最多,返回最多的宣讲场次
|
|
|
|
|
|
|
|
|
|
输入正数数组costs、正数数组profits、正数K和正数M
|
|
|
|
|
costs[i]表示i号项目的花费
|
|
|
|
|
profits[i]表示i号项目在扣除花费之后还能挣到的钱(利润)
|
|
|
|
|
K表示你只能串行的最多做k个项目
|
|
|
|
|
M表示你初始的资金
|
|
|
|
|
说明:每做完一个项目,马上获得的收益,可以支持你去做下一个项目,不能并行的做项目。
|
|
|
|
|
输出:最后获得的最大钱数
|
|
|
|
|
|
|
|
|
|
并查集的实现
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
15 并查集相关的常见面试题
|
|
|
|
|
|
|
|
|
|
内容:
|
|
|
|
|
|
|
|
|
|
通过解答实际出现的面试题来体会并查集的优势、熟悉并查集的使用
|
|
|
|
|
|
|
|
|
|
题目:
|
|
|
|
|
|
|
|
|
|
一群朋友中,有几个不相交的朋友圈
|
|
|
|
|
Leetcode题目:https://leetcode.com/problems/friend-circles/
|
|
|
|
|
|
|
|
|
|
岛问题(递归解法 + 并查集解法 + 并行解法)
|
|
|
|
|
给定一个二维数组matrix,里面的值不是1就是0,上、下、左、右相邻的1认为是一片岛,返回matrix中岛的数量
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
16 图及其与图相关的算法
|
|
|
|
|
|
|
|
|
|
内容:
|
|
|
|
|
|
|
|
|
|
图的表达方式
|
|
|
|
|
|
|
|
|
|
图的常见描述
|
|
|
|
|
|
|
|
|
|
图的宽度优先遍历
|
|
|
|
|
|
|
|
|
|
图的深度优先遍历
|
|
|
|
|
|
|
|
|
|
图的拓扑排序
|
|
|
|
|
|
|
|
|
|
最小生成树算法Kruskal
|
|
|
|
|
|
|
|
|
|
最小生成树算法Prim
|
|
|
|
|
|
|
|
|
|
单元最短路径算法Dijkstra
|
|
|
|
|
|
|
|
|
|
题目:
|
|
|
|
|
|
|
|
|
|
图的数据结构抽象
|
|
|
|
|
|
|
|
|
|
实现图的宽度优先遍历
|
|
|
|
|
|
|
|
|
|
实现图的深度优先遍历
|
|
|
|
|
|
|
|
|
|
三种方式实现图的拓扑排序
|
|
|
|
|
|
|
|
|
|
用并查集实现Kruskal算法
|
|
|
|
|
|
|
|
|
|
用堆实现Prim算法
|
|
|
|
|
|
|
|
|
|
实现Dijkstra算法,用加强堆做更好的实现(16节+17节一开始)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
17 用加强堆更好的实现Dijkstra算法、常见的递归
|
|
|
|
|
|
|
|
|
|
内容:
|
|
|
|
|
|
|
|
|
|
加强堆实现Dijkstra算法
|
|
|
|
|
|
|
|
|
|
递归的设计
|
|
|
|
|
|
|
|
|
|
常见的递归
|
|
|
|
|
|
|
|
|
|
题目:
|
|
|
|
|
|
|
|
|
|
打印n层汉诺塔从最左边移动到最右边的全部过程(递归+非递归实现)
|
|
|
|
|
|
|
|
|
|
打印一个字符串的全部子序列
|
|
|
|
|
|
|
|
|
|
打印一个字符串的全部子序列,要求不要出现重复字面值的子序列
|
|
|
|
|
|
|
|
|
|
打印一个字符串的全部排列
|
|
|
|
|
|
|
|
|
|
打印一个字符串的全部排列,要求不要出现重复的排列
|
|
|
|
|
|
|
|
|
|
给定一个栈,请逆序这个栈,不能申请额外的数据结构,只能使用递归函数
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
18 暴力递归到动态规划(一)
|
|
|
|
|
|
|
|
|
|
内容:
|
|
|
|
|
|
|
|
|
|
讲述暴力递归和动态规划的关系
|
|
|
|
|
|
|
|
|
|
记忆化搜索
|
|
|
|
|
|
|
|
|
|
动态规划都可以由暴力递归改进过来,解决动态规划的套路
|
|
|
|
|
|
|
|
|
|
常见的尝试模型
|
|
|
|
|
|
|
|
|
|
设计尝试过程的原则
|
|
|
|
|
|
|
|
|
|
本节是暴力递归到动态规划的总纲(很重要)
|
|
|
|
|
|
|
|
|
|
后续的课都是在讲述这一系列的套路
|
|
|
|
|
|
|
|
|
|
题目:
|
|
|
|
|
|
|
|
|
|
假设有排成一行的N个位置记为1~N,N一定大于或等于2
|
|
|
|
|
开始时机器人在其中的M位置上(M一定是1~N中的一个)
|
|
|
|
|
如果机器人来到1位置,那么下一步只能往右来到2位置;
|
|
|
|
|
如果机器人来到N位置,那么下一步只能往左来到N-1位置;
|
|
|
|
|
如果机器人来到中间位置,那么下一步可以往左走或者往右走;
|
|
|
|
|
规定机器人必须走K步,最终能来到P位置(P也是1~N中的一个)的方法有多少种
|
|
|
|
|
给定四个参数 N、M、K、P,返回方法数
|
|
|
|
|
|
|
|
|
|
给定一个整型数组arr,代表数值不同的纸牌排成一条线
|
|
|
|
|
玩家A和玩家B依次拿走每张纸牌
|
|
|
|
|
规定玩家A先拿,玩家B后拿
|
|
|
|
|
但是每个玩家每次只能拿走最左或最右的纸牌
|
|
|
|
|
玩家A和玩家B都绝顶聪明
|
|
|
|
|
请返回最后获胜者的分数
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
19 暴力递归到动态规划(二)
|
|
|
|
|
|
|
|
|
|
内容:
|
|
|
|
|
|
|
|
|
|
以18节为总纲
|
|
|
|
|
|
|
|
|
|
背包问题
|
|
|
|
|
|
|
|
|
|
记忆化搜索的一个很重要的注意点
|
|
|
|
|
|
|
|
|
|
通过面试题进一步强化动态规划的解题套路
|
|
|
|
|
|
|
|
|
|
题目:
|
|
|
|
|
|
|
|
|
|
背包问题
|
|
|
|
|
给定两个长度都为N的数组weights和values,weights[i]和values[i]分别代表 i号物品的重量和价值
|
|
|
|
|
给定一个正数bag,表示一个载重bag的袋子,装的物品不能超过这个重量
|
|
|
|
|
返回能装下的最大价值
|
|
|
|
|
|
|
|
|
|
规定1和A对应、2和B对应、3和C对应...26和Z对应
|
|
|
|
|
那么一个数字字符串比如"111”就可以转化为:
|
|
|
|
|
"AAA"、"KA"和"AK"
|
|
|
|
|
给定一个只有数字字符组成的字符串str,返回有多少种转化结果
|
|
|
|
|
|
|
|
|
|
给定一个字符串str,给定一个字符串类型的数组arr,出现的字符都是小写英文
|
|
|
|
|
arr每一个字符串,代表一张贴纸,你可以把单个字符剪开使用,目的是拼出str来
|
|
|
|
|
返回需要至少多少张贴纸可以完成这个任务
|
|
|
|
|
例子:str= "babac",arr = {"ba","c","abcd"}
|
|
|
|
|
ba + ba + c 3 abcd + abcd 2 abcd+ba 2
|
|
|
|
|
所以返回2
|
|
|
|
|
|
|
|
|
|
给定两个字符串str1和str2,
|
|
|
|
|
返回这两个字符串的最长公共子序列长度
|
|
|
|
|
比如 : str1 = “a12b3c456d”,str2 = “1ef23ghi4j56k”
|
|
|
|
|
最长公共子序列是“123456”,所以返回长度6
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
20 暴力递归到动态规划(三)
|
|
|
|
|
|
|
|
|
|
内容:
|
|
|
|
|
|
|
|
|
|
以18节为总纲
|
|
|
|
|
|
|
|
|
|
通过面试题进一步强化动态规划的解题套路
|
|
|
|
|
|
|
|
|
|
题目:
|
|
|
|
|
|
|
|
|
|
给定一个字符串str,返回这个字符串的最长回文子序列长度
|
|
|
|
|
比如 : str = “a12b3c43def2ghi1kpm”
|
|
|
|
|
最长回文子序列是“1234321”或者“123c321”,返回长度7
|
|
|
|
|
|
|
|
|
|
请同学们自行搜索或者想象一个象棋的棋盘,
|
|
|
|
|
然后把整个棋盘放入第一象限,棋盘的最左下角是(0,0)位置
|
|
|
|
|
那么整个棋盘就是横坐标上9条线、纵坐标上10条线的区域
|
|
|
|
|
给你三个 参数 x,y,k
|
|
|
|
|
返回“马”从(0,0)位置出发,必须走k步
|
|
|
|
|
最后落在(x,y)上的方法数有多少种?
|
|
|
|
|
|
|
|
|
|
给定一个数组arr,arr[i]代表第i号咖啡机泡一杯咖啡的时间
|
|
|
|
|
给定一个正数N,表示N个人等着咖啡机泡咖啡,每台咖啡机只能轮流泡咖啡
|
|
|
|
|
只有一台咖啡机,一次只能洗一个杯子,时间耗费a,洗完才能洗下一杯
|
|
|
|
|
每个咖啡杯也可以自己挥发干净,时间耗费b,咖啡杯可以并行挥发
|
|
|
|
|
假设所有人拿到咖啡之后立刻喝干净,
|
|
|
|
|
返回从开始等到所有咖啡机变干净的最短时间
|
|
|
|
|
三个参数:int[] arr、int N,int a、int b
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
21 暴力递归到动态规划(四)
|
|
|
|
|
|
|
|
|
|
内容:
|
|
|
|
|
|
|
|
|
|
以18节为总纲
|
|
|
|
|
|
|
|
|
|
通过面试题进一步强化动态规划的解题套路
|
|
|
|
|
|
|
|
|
|
题目:
|
|
|
|
|
|
|
|
|
|
给定一个二维数组matrix,一个人必须从左上角出发,最后到达右下角
|
|
|
|
|
沿途只可以向下或者向右走,沿途的数字都累加就是距离累加和
|
|
|
|
|
返回最小距离累加和
|
|
|
|
|
|
|
|
|
|
arr是货币数组,其中的值都是正数。再给定一个正数aim。
|
|
|
|
|
每个值都认为是一张货币,
|
|
|
|
|
即便是值相同的货币也认为每一张都是不同的,
|
|
|
|
|
返回组成aim的方法数
|
|
|
|
|
例如:arr = {1,1,1},aim = 2
|
|
|
|
|
第0个和第1个能组成2,第1个和第2个能组成2,第0个和第2个能组成2
|
|
|
|
|
一共就3种方法,所以返回3
|
|
|
|
|
|
|
|
|
|
arr是面值数组,其中的值都是正数且没有重复。再给定一个正数aim。
|
|
|
|
|
每个值都认为是一种面值,且认为张数是无限的。
|
|
|
|
|
返回组成aim的方法数
|
|
|
|
|
例如:arr = {1,2},aim = 4
|
|
|
|
|
方法如下:1+1+1+1、1+1+2、2+2
|
|
|
|
|
一共就3种方法,所以返回3
|
|
|
|
|
|
|
|
|
|
arr是货币数组,其中的值都是正数。再给定一个正数aim。
|
|
|
|
|
每个值都认为是一张货币,
|
|
|
|
|
认为值相同的货币没有任何不同,
|
|
|
|
|
返回组成aim的方法数
|
|
|
|
|
例如:arr = {1,2,1,1,2,1,2},aim = 4
|
|
|
|
|
方法:1+1+1+1、1+1+2、2+2
|
|
|
|
|
一共就3种方法,所以返回3
|
|
|
|
|
|
|
|
|
|
给定5个参数,N,M,row,col,k
|
|
|
|
|
表示在N*M的区域上,醉汉Bob初始在(row,col)位置
|
|
|
|
|
Bob一共要迈出k步,且每步都会等概率向上下左右四个方向走一个单位
|
|
|
|
|
任何时候Bob只要离开N*M的区域,就直接死亡
|
|
|
|
|
返回k步之后,Bob还在N*M的区域的概率
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
22 暴力递归到动态规划(五)
|
|
|
|
|
|
|
|
|
|
内容:
|
|
|
|
|
|
|
|
|
|
以18节为总纲
|
|
|
|
|
|
|
|
|
|
通过面试题进一步强化动态规划的解题套路
|
|
|
|
|
|
|
|
|
|
斜率优化技巧
|
|
|
|
|
|
|
|
|
|
题目:
|
|
|
|
|
|
|
|
|
|
给定3个参数,N,M,K
|
|
|
|
|
怪兽有N滴血,等着英雄来砍自己
|
|
|
|
|
英雄每一次打击,都会让怪兽流失[0~M]的血量
|
|
|
|
|
到底流失多少?每一次在[0~M]上等概率的获得一个值
|
|
|
|
|
求K次打击之后,英雄把怪兽砍死的概率
|
|
|
|
|
|
|
|
|
|
arr是面值数组,其中的值都是正数且没有重复。再给定一个正数aim。
|
|
|
|
|
每个值都认为是一种面值,且认为张数是无限的。
|
|
|
|
|
返回组成aim的最少货币数
|
|
|
|
|
|
|
|
|
|
给定一个正数n,求n的裂开方法数,
|
|
|
|
|
规定:后面的数不能比前面的数小
|
|
|
|
|
比如4的裂开方法有:
|
|
|
|
|
1+1+1+1、1+1+2、1+3、2+2、4
|
|
|
|
|
5种,所以返回5
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
23 暴力递归到动态规划(六)
|
|
|
|
|
|
|
|
|
|
内容:
|
|
|
|
|
|
|
|
|
|
以18节为总纲
|
|
|
|
|
|
|
|
|
|
通过面试题进一步强化动态规划的解题套路
|
|
|
|
|
|
|
|
|
|
位信息技巧
|
|
|
|
|
|
|
|
|
|
题目:
|
|
|
|
|
|
|
|
|
|
给定一个正数数组arr,
|
|
|
|
|
请把arr中所有的数分成两个集合,尽量让两个集合的累加和接近
|
|
|
|
|
返回最接近的情况下,较小集合的累加和
|
|
|
|
|
|
|
|
|
|
给定一个正数数组arr,请把arr中所有的数分成两个集合
|
|
|
|
|
如果arr长度为偶数,两个集合包含数的个数要一样多
|
|
|
|
|
如果arr长度为奇数,两个集合包含数的个数必须只差一个
|
|
|
|
|
请尽量让两个集合的累加和接近
|
|
|
|
|
返回最接近的情况下,较小集合的累加和
|
|
|
|
|
|
|
|
|
|
N皇后问题是指在N*N的棋盘上要摆N个皇后,
|
|
|
|
|
要求任何两个皇后不同行、不同列, 也不在同一条斜线上
|
|
|
|
|
给定一个整数n,返回n皇后的摆法有多少种。n=1,返回1
|
|
|
|
|
n=2或3,2皇后和3皇后问题无论怎么摆都不行,返回0
|
|
|
|
|
n=8,返回92
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
24 窗口内最大值或最小值的更新结构
|
|
|
|
|
|
|
|
|
|
内容:
|
|
|
|
|
|
|
|
|
|
滑动窗口
|
|
|
|
|
|
|
|
|
|
窗口内最大值或最小值的更新结构
|
|
|
|
|
|
|
|
|
|
用题目来学习窗口内最大值或最小值的更新结构提供的便利性
|
|
|
|
|
|
|
|
|
|
题目:
|
|
|
|
|
|
|
|
|
|
窗口内最大值或最小值更新结构的实现
|
|
|
|
|
假设一个固定大小为W的窗口,依次划过arr,
|
|
|
|
|
返回每一次滑出状况的最大值
|
|
|
|
|
例如,arr = [4,3,5,4,3,3,6,7], W = 3
|
|
|
|
|
返回:[5,5,5,4,6,7]
|
|
|
|
|
|
|
|
|
|
给定一个整型数组arr,和一个整数num
|
|
|
|
|
某个arr中的子数组sub,如果想达标,必须满足:sub中最大值 – sub中最小值 <= num,
|
|
|
|
|
返回arr中达标子数组的数量
|
|
|
|
|
|
|
|
|
|
加油站的良好出发点问题
|
|
|
|
|
|
|
|
|
|
动态规划中利用窗口内最大值或最小值更新结构做优化(难)
|
|
|
|
|
arr是货币数组,其中的值都是正数。再给定一个正数aim。
|
|
|
|
|
每个值都认为是一张货币,
|
|
|
|
|
返回组成aim的最少货币数
|
|
|
|
|
注意:因为是求最少货币数,所以每一张货币认为是相同或者不同就不重要了
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
25 单调栈
|
|
|
|
|
|
|
|
|
|
内容:
|
|
|
|
|
|
|
|
|
|
单调栈的原理(无重复数+有重复数)
|
|
|
|
|
|
|
|
|
|
用题目来学习单调栈提供的便利性
|
|
|
|
|
|
|
|
|
|
题目:
|
|
|
|
|
|
|
|
|
|
单调栈实现(无重复数+有重复数)
|
|
|
|
|
|
|
|
|
|
给定一个只包含正数的数组arr,arr中任何一个子数组sub,
|
|
|
|
|
一定都可以算出(sub累加和 )* (sub中的最小值)是什么,
|
|
|
|
|
那么所有子数组中,这个值最大是多少?
|
|
|
|
|
|
|
|
|
|
给定一个非负数组arr,代表直方图,返回直方图的最大长方形面积
|
|
|
|
|
|
|
|
|
|
给定一个二维数组matrix,其中的值不是0就是1,返回全部由1组成的最大子矩形内部有多少个1(面积)
|
|
|
|
|
|
|
|
|
|
给定一个二维数组matrix,其中的值不是0就是1,返回全部由1组成的子矩形数量
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
26 单调栈相关的题目(续)、斐波那契数列的矩阵快速幂模型
|
|
|
|
|
|
|
|
|
|
内容:
|
|
|
|
|
|
|
|
|
|
再讲一个单调栈相关的面试题
|
|
|
|
|
|
|
|
|
|
斐波那契数列的矩阵快速幂模型详解
|
|
|
|
|
|
|
|
|
|
题目:
|
|
|
|
|
|
|
|
|
|
给定一个数组arr,返回所有子数组最小值的累加和
|
|
|
|
|
|
|
|
|
|
斐波那契数列矩阵乘法方式的实现
|
|
|
|
|
|
|
|
|
|
台阶方法数问题
|
|
|
|
|
一个人可以一次往上迈1个台阶,也可以迈2个台阶,返回迈上N级台阶的方法数
|
|
|
|
|
|
|
|
|
|
奶牛生小牛问题
|
|
|
|
|
第一年农场有1只成熟的母牛A,往后的每年:
|
|
|
|
|
1)每一只成熟的母牛都会生一只母牛
|
|
|
|
|
2)每一只新出生的母牛都在出生的第三年成熟
|
|
|
|
|
3)每一只母牛永远不会死
|
|
|
|
|
返回N年后牛的数量
|
|
|
|
|
|
|
|
|
|
给定一个数N,想象只由0和1两种字符,组成的所有长度为N的字符串
|
|
|
|
|
如果某个字符串,任何0字符的左边都有1紧挨着,认为这个字符串达标
|
|
|
|
|
返回有多少达标的字符串
|
|
|
|
|
|
|
|
|
|
用1*2的瓷砖,把N*2的区域填满,返回铺瓷砖的方法数
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
27 KMP算法
|
|
|
|
|
|
|
|
|
|
内容:
|
|
|
|
|
|
|
|
|
|
KMP算法
|
|
|
|
|
|
|
|
|
|
和KMP算法相关的面试题
|
|
|
|
|
|
|
|
|
|
题目:
|
|
|
|
|
|
|
|
|
|
KMP算法实现
|
|
|
|
|
|
|
|
|
|
给定两棵二叉树的头节点head1和head2,返回head1中是否有某个子树的结构和head2完全一样
|
|
|
|
|
|
|
|
|
|
判断str1和str2是否互为旋转字符串
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
28 Manacher算法
|
|
|
|
|
|
|
|
|
|
内容:
|
|
|
|
|
|
|
|
|
|
Manacher算法
|
|
|
|
|
|
|
|
|
|
和Manacher算法相关的面试题
|
|
|
|
|
|
|
|
|
|
题目:
|
|
|
|
|
|
|
|
|
|
Manacher算法实现
|
|
|
|
|
|
|
|
|
|
给定一个字符串str,只能在str的后面添加字符,想让str整体变成回文串,返回至少要添加几个字符
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
29 在无序数组中找到第K小的数、蓄水池算法
|
|
|
|
|
|
|
|
|
|
内容:
|
|
|
|
|
|
|
|
|
|
时间复杂度O(N)可以解决在无序数组中找到第K小的数,这个经典的面试题
|
|
|
|
|
|
|
|
|
|
改写快排的partition方法
|
|
|
|
|
|
|
|
|
|
bfprt算法
|
|
|
|
|
|
|
|
|
|
蓄水池算法
|
|
|
|
|
|
|
|
|
|
题目:
|
|
|
|
|
|
|
|
|
|
在无序数组中找到第K小的数(改写快排+bfprt)
|
|
|
|
|
|
|
|
|
|
设计在无序数组中收集最大的前K个数字的算法(根据不同的三个时间复杂度,设计三个算法)
|
|
|
|
|
给定一个无序数组arr中,长度为N,给定一个正数k,返回top k个最大的数
|
|
|
|
|
不同时间复杂度三个方法:
|
|
|
|
|
1)O(N*logN)
|
|
|
|
|
2)O(N + K*logN)
|
|
|
|
|
3)O(n + k*logk)
|
|
|
|
|
|
|
|
|
|
蓄水池算法实现
|
|
|
|
|
假设有一个源源吐出不同球的机器,
|
|
|
|
|
只有装下10个球的袋子,每一个吐出的球,要么放入袋子,要么永远扔掉
|
|
|
|
|
如何做到机器吐出每一个球之后,所有吐出的球都等概率被放进袋子里
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
30 二叉树的Morris遍历
|
|
|
|
|
|
|
|
|
|
内容:
|
|
|
|
|
|
|
|
|
|
二叉树之前的遍历方式有空间浪费的问题
|
|
|
|
|
|
|
|
|
|
Morris遍历时间复杂度O(N),额外空间复杂度O(1),通过利用原树中大量空闲指针的方式,达到节省空间的目的
|
|
|
|
|
|
|
|
|
|
假设来到当前节点cur,开始时cur来到头节点位置
|
|
|
|
|
1)如果cur没有左孩子,cur向右移动(cur = cur.right)
|
|
|
|
|
2)如果cur有左孩子,找到左子树上最右的节点mostRight:
|
|
|
|
|
a.如果mostRight的右指针指向空,让其指向cur,
|
|
|
|
|
然后cur向左移动(cur = cur.left)
|
|
|
|
|
b.如果mostRight的右指针指向cur,让其指向null,
|
|
|
|
|
然后cur向右移动(cur = cur.right)
|
|
|
|
|
3)cur为空时遍历停止
|
|
|
|
|
|
|
|
|
|
Morris遍历实现二叉树的先序、中序、后序遍历
|
|
|
|
|
|
|
|
|
|
题目:
|
|
|
|
|
|
|
|
|
|
Morris遍历的实现
|
|
|
|
|
|
|
|
|
|
给定一棵二叉树的头节点head,求以head为头的树中,最小深度是多少?
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
31 线段树
|
|
|
|
|
|
|
|
|
|
内容:
|
|
|
|
|
|
|
|
|
|
线段树是一种支持范围整体修改和范围整体查询的数据结构
|
|
|
|
|
|
|
|
|
|
线段树解决的问题范畴:大范围信息可以只由左、右两侧信息加工出,而不必遍历左右两个子范围的具体状况
|
|
|
|
|
|
|
|
|
|
题目:
|
|
|
|
|
|
|
|
|
|
给定一个数组arr,用户希望你实现如下三个方法
|
|
|
|
|
1)void add(int L, int R, int V) : 让数组arr[L…R]上每个数都加上V
|
|
|
|
|
2)void update(int L, int R, int V) : 让数组arr[L…R]上每个数都变成V
|
|
|
|
|
3)int sum(int L, int R) :让返回arr[L…R]这个范围整体的累加和
|
|
|
|
|
怎么让这三个方法,时间复杂度都是O(logN)
|
|
|
|
|
|
|
|
|
|
想象一下标准的俄罗斯方块游戏,X轴是积木最终下落到底的轴线
|
|
|
|
|
下面是这个游戏的简化版:
|
|
|
|
|
1)只会下落正方形积木
|
|
|
|
|
2)[a,b] -> 代表一个边长为b的正方形积木,积木左边缘沿着X = a这条线从上方掉落
|
|
|
|
|
3)认为整个X轴都可能接住积木,也就是说简化版游戏是没有整体的左右边界的
|
|
|
|
|
4)没有整体的左右边界,所以简化版游戏不会消除积木,因为不会有哪一层被填满。
|
|
|
|
|
给定一个N*2的二维数组matrix,可以代表N个积木依次掉落,
|
|
|
|
|
返回每一次掉落之后的最大高度
|
|
|
|
|
Leetcode题目:https://leetcode.com/problems/falling-squares/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
32 IndexTree、AC自动机
|
|
|
|
|
|
|
|
|
|
内容:
|
|
|
|
|
|
|
|
|
|
IndexTree
|
|
|
|
|
1)支持区间查询
|
|
|
|
|
2)没有线段树那么强,但是非常容易改成一维、二维、三维的结构
|
|
|
|
|
3)只支持单点更新
|
|
|
|
|
|
|
|
|
|
AC自动机
|
|
|
|
|
解决在一个大字符串中,找到多个候选字符串的问题
|
|
|
|
|
1)把所有匹配串生成一棵前缀树
|
|
|
|
|
2)前缀树节点增加fail指针
|
|
|
|
|
3)fail指针的含义:如果必须以当前字符结尾,当前形成的路径是str,剩下哪一个字符串的前缀和str的后缀
|
|
|
|
|
拥有最大的匹配长度。fail指针就指向那个字符串的最后一个字符所对应的节点(迷不迷?听讲述!)
|
|
|
|
|
|
|
|
|
|
题目:
|
|
|
|
|
|
|
|
|
|
IndexTree在一维数组和二维数组上的实现
|
|
|
|
|
|
|
|
|
|
AC自动机的实现
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
33 与哈希函数有关的结构
|
|
|
|
|
|
|
|
|
|
内容:
|
|
|
|
|
|
|
|
|
|
哈希函数
|
|
|
|
|
|
|
|
|
|
哈希函数的应用
|
|
|
|
|
|
|
|
|
|
布隆过滤器
|
|
|
|
|
|
|
|
|
|
一致性哈希
|
|
|
|
|
|
|
|
|
|
题目:
|
|
|
|
|
|
|
|
|
|
原理讲述为主,面试只会聊设计,所以本节无题目
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
34 资源限制类题目的解题套路
|
|
|
|
|
|
|
|
|
|
内容:
|
|
|
|
|
|
|
|
|
|
布隆过滤器用于集合的建立与查询,并可以节省大量空间
|
|
|
|
|
一致性哈希解决数据服务器的负载管理问题
|
|
|
|
|
利用并查集结构做岛问题的并行计算
|
|
|
|
|
哈希函数可以把数据按照种类均匀分流
|
|
|
|
|
位图解决某一范围上数字的出现情况,并可以节省大量空间
|
|
|
|
|
利用分段统计思想、并进一步节省大量空间
|
|
|
|
|
利用堆、外排序来做多个处理单元的结果合并
|
|
|
|
|
|
|
|
|
|
题目:
|
|
|
|
|
|
|
|
|
|
32位无符号整数的范围是0~4,294,967,295,
|
|
|
|
|
现在有一个正好包含40亿个无符号整数的文件,
|
|
|
|
|
可以使用最多1GB的内存,怎么找到出现次数最多的数?
|
|
|
|
|
|
|
|
|
|
32位无符号整数的范围是0~4,294,967,295,现在有一个正好包含40亿个无符号整数的文件,
|
|
|
|
|
所以在整个范围中必然存在没出现过的数,可以使用最多1GB的内存,怎么找到所有未出现过的数?
|
|
|
|
|
进阶:内存限制为 3KB,但是只用找到一个没出现过的数即可
|
|
|
|
|
|
|
|
|
|
有一个包含100亿个URL的大文件,假设每个URL占用64B,请找出其中所有重复的URL
|
|
|
|
|
补充:某搜索公司一天的用户搜索词汇是海量的(百亿数据量),请设计一种求出每天热门Top100词汇的可行办法
|
|
|
|
|
|
|
|
|
|
32位无符号整数的范围是0~4294967295,现在有40亿个无符号整数,可以使用最多1GB的内存,找出所有出现了两次的数
|
|
|
|
|
|
|
|
|
|
32位无符号整数的范围是0~4294967295,现在有40亿个无符号整数,可以使用最多3K的内存,怎么找到这40亿个整数的中位数?
|
|
|
|
|
|
|
|
|
|
32位无符号整数的范围是0~4294967295,有一个10G大小的文件,每一行都装着这种类型的数字,
|
|
|
|
|
整个文件是无序的,给你5G的内存空间,请你输出一个10G大小的文件,就是原文件所有数字排序的结果
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
35 有序表(上)
|
|
|
|
|
|
|
|
|
|
内容:
|
|
|
|
|
|
|
|
|
|
平衡搜索二叉树
|
|
|
|
|
|
|
|
|
|
左旋
|
|
|
|
|
|
|
|
|
|
右旋
|
|
|
|
|
|
|
|
|
|
AVL树的节点违规4种类型(LL,LR,RL,RR)
|
|
|
|
|
|
|
|
|
|
题目:
|
|
|
|
|
|
|
|
|
|
AVL树的实现
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
36 有序表(中)
|
|
|
|
|
|
|
|
|
|
内容:
|
|
|
|
|
|
|
|
|
|
size-balanced-tree详解
|
|
|
|
|
|
|
|
|
|
skiplist详解
|
|
|
|
|
|
|
|
|
|
聊聊红黑树
|
|
|
|
|
|
|
|
|
|
题目:
|
|
|
|
|
|
|
|
|
|
size-balanced-tree实现
|
|
|
|
|
|
|
|
|
|
skiplist实现
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
37 有序表(下)
|
|
|
|
|
|
|
|
|
|
内容:
|
|
|
|
|
|
|
|
|
|
讲解有序表相关的面试题
|
|
|
|
|
|
|
|
|
|
讲解改写有序表的题目核心点
|
|
|
|
|
|
|
|
|
|
题目:
|
|
|
|
|
|
|
|
|
|
给定一个数组arr,和两个整数a和b(a<=b)。求arr中有多少个子数组,累加和在[a,b]这个范围上。返回达标的子数组数量
|
|
|
|
|
|
|
|
|
|
有一个滑动窗口:
|
|
|
|
|
1)L是滑动窗口最左位置、R是滑动窗口最右位置,一开始LR都在数组左侧
|
|
|
|
|
2)任何一步都可能R往右动,表示某个数进了窗口
|
|
|
|
|
3)任何一步都可能L往右动,表示某个数出了窗口
|
|
|
|
|
想知道每一个窗口状态的中位数
|
|
|
|
|
|
|
|
|
|
设计一个结构包含如下两个方法:
|
|
|
|
|
void add(int index, int num):把num加入到index位置
|
|
|
|
|
int get(int index) :取出index位置的值
|
|
|
|
|
void remove(int index) :把index位置上的值删除
|
|
|
|
|
要求三个方法时间复杂度O(logN)
|
|
|
|
|
|
|
|
|
|
假设有打乱顺序的一群人站成一个队列,数组people表示队列中一些人的属性(不一定按顺序)
|
|
|
|
|
每个people[i]=[hi, ki]表示第i个人的身高为hi,前面正好有ki个身高大于或等于hi的人
|
|
|
|
|
请你重新构造并返回输入数组people所表示的队列,返回的队列应该格式化为数组queue
|
|
|
|
|
其中queue[j]=[hj, kj]是队列中第j个人的属性(queue[0] 是排在队列前面的人)。
|
|
|
|
|
Leetcode题目:https://leetcode.com/problems/queue-reconstruction-by-height/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
38 根据对数器找规律、根据数据量猜解法
|
|
|
|
|
|
|
|
|
|
内容:
|
|
|
|
|
|
|
|
|
|
讲解对数器找规律的解题技巧
|
|
|
|
|
|
|
|
|
|
讲解根据数据量猜解法的技巧
|
|
|
|
|
1)C/C++,1秒处理的指令条数为10的8次方
|
|
|
|
|
2)Java等语言,1~4秒处理的指令条数为10的8次方
|
|
|
|
|
3)这里就有大量的分析提示了
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
题目:
|
|
|
|
|
|
|
|
|
|
小虎去买苹果,商店只提供两种类型的塑料袋,每种类型都有任意数量
|
|
|
|
|
1)能装下6个苹果的袋子
|
|
|
|
|
2)能装下8个苹果的袋子
|
|
|
|
|
小虎可以自由使用两种袋子来装苹果,但是小虎有强迫症,他要求自己使用的袋子数量必须最少,
|
|
|
|
|
且使用的每个袋子必须装满,给定一个正整数N,返回至少使用多少袋子。如果N无法让使用的每个袋子必须装满,返回-1
|
|
|
|
|
|
|
|
|
|
给定一个正整数N,表示有N份青草统一堆放在仓库里,有一只牛和一只羊,牛先吃,羊后吃,它俩轮流吃草
|
|
|
|
|
不管是牛还是羊,每一轮能吃的草量必须是:1,4,16,64…(4的某次方)
|
|
|
|
|
谁最先把草吃完,谁获胜,假设牛和羊都绝顶聪明,都想赢,都会做出理性的决定。根据唯一的参数N,返回谁会赢
|
|
|
|
|
|
|
|
|
|
定义一种数:可以表示成若干(数量>1)连续正数和的数
|
|
|
|
|
比如,5=2+3,5就是这样的数;12=3+4+5,12就是这样的数
|
|
|
|
|
2=1+1,2不是这样的数,因为等号右边不是连续正数
|
|
|
|
|
给定一个参数N,返回是不是可以表示成若干连续正数和的数
|
|
|
|
|
|
|
|
|
|
int[] d,d[i]:i号怪兽的能力
|
|
|
|
|
int[] p,p[i]:i号怪兽要求的钱
|
|
|
|
|
开始时你的能力是0,你的目标是从0号怪兽开始,通过所有的怪兽。
|
|
|
|
|
如果你当前的能力,小于i号怪兽的能力,你必须付出p[i]的钱,贿赂这个怪兽,然后怪兽就会加入你
|
|
|
|
|
他的能力直接累加到你的能力上;如果你当前的能力,大于等于i号怪兽的能力
|
|
|
|
|
你可以选择直接通过,你的能力并不会下降,你也可以选择贿赂这个怪兽,然后怪兽就会加入你
|
|
|
|
|
他的能力直接累加到你的能力上
|
|
|
|
|
返回通过所有的怪兽,需要花的最小钱数
|
|
|
|
|
(课上会给出不同的数据量描述)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
39 根据数据量猜解法(续)、分治技巧、卡特兰数
|
|
|
|
|
|
|
|
|
|
内容:
|
|
|
|
|
|
|
|
|
|
继续熟悉根据数据量猜解法
|
|
|
|
|
|
|
|
|
|
讲解分治法
|
|
|
|
|
|
|
|
|
|
讲解卡特兰数(课上证明的时候有小错,在40节开始处修正了)
|
|
|
|
|
|
|
|
|
|
题目:
|
|
|
|
|
|
|
|
|
|
给定一个非负数组arr,和一个正数m,返回arr的所有子序列中累加和%m之后的最大值
|
|
|
|
|
|
|
|
|
|
牛牛家里一共有n袋零食, 第i袋零食体积为v[i],背包容量为w,牛牛想知道在总体积不超过背包容量的情况下,
|
|
|
|
|
一共有多少种零食放法,体积为0也算一种放法
|
|
|
|
|
1 <= n <= 30, 1 <= w <= 2 * 10^9,v[I] (0 <= v[i] <= 10^9)
|
|
|
|
|
|
|
|
|
|
假设给你N个0,和N个1,你必须用全部数字拼序列,返回有多少个序列满足任何前缀串,1的数量都不少于0的数量
|
|
|
|
|
|
|
|
|
|
有N个二叉树节点,每个节点彼此之间无任何差别,返回由N个二叉树节点,组成的不同结构数量是多少?
|
|
|
|
|
|
|
|
|
|
题目补充: arr中的值可能为正,可能为负,可能为0,自由选择arr中的数字,能不能累加得到sum(多种做法)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
40 子数组达到规定累加和的最大长度系列问题、矩阵处理技巧题
|
|
|
|
|
|
|
|
|
|
内容:
|
|
|
|
|
|
|
|
|
|
修正了39节卡特兰数讲解时的一个小错误
|
|
|
|
|
|
|
|
|
|
熟悉子数组达到规定累加和的三个模型(正、有正有负有0、累加和<=K)
|
|
|
|
|
|
|
|
|
|
矩阵处理技巧的宏观调度coding技巧
|
|
|
|
|
|
|
|
|
|
题目:
|
|
|
|
|
|
|
|
|
|
给定一个正整数组成的无序数组arr,给定一个正整数值K,找到arr的所有子数组里,哪个子数组的累加和等于K
|
|
|
|
|
并且是长度最大的,返回其长度
|
|
|
|
|
|
|
|
|
|
给定一个整数组成的无序数组arr,值可能正、可能负、可能0,给定一个整数值K
|
|
|
|
|
找到arr的所有子数组里,哪个子数组的累加和等于K,并且是长度最大的,返回其长度
|
|
|
|
|
|
|
|
|
|
给定一个整数组成的无序数组arr,值可能正、可能负、可能0,给定一个整数值K
|
|
|
|
|
找到arr的所有子数组里,哪个子数组的累加和<=K,并且是长度最大的,返回其长度
|
|
|
|
|
|
|
|
|
|
给定一个数组arr,给定一个值v,求子数组平均值小于等于v的最长子数组长度
|
|
|
|
|
|
|
|
|
|
给定一个正方形矩阵matrix,原地调整成顺时针90度转动的样子
|
|
|
|
|
|
|
|
|
|
给定一个正方形或者长方形矩阵matrix,实现转圈打印
|
|
|
|
|
|
|
|
|
|
给定一个正方形或者长方形矩阵matrix,实现zigzag打印
|
|
|
|
|
|
|
|
|
|
转圈打印星号*问题
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
41 四边形不等式技巧(上)
|
|
|
|
|
|
|
|
|
|
内容:
|
|
|
|
|
|
|
|
|
|
区间划分问题中的划分点不回退现象
|
|
|
|
|
|
|
|
|
|
四边形不等式技巧特征
|
|
|
|
|
1,两个可变参数的区间划分问题
|
|
|
|
|
2,每个格子有枚举行为
|
|
|
|
|
3,当两个可变参数固定一个,另一个参数和答案之间存在单调性关系
|
|
|
|
|
4,而且两组单调关系是反向的:(升 升,降 降) (升 降,降 升)
|
|
|
|
|
5,能否获得指导枚举优化的位置对:上+右,或者,左+下
|
|
|
|
|
|
|
|
|
|
四边形不等式技巧注意点
|
|
|
|
|
1,不要证明!用对数器验证!
|
|
|
|
|
2,枚举的时候面对最优答案相等的时候怎么处理?用对数器都试试!
|
|
|
|
|
3,可以把时间复杂度降低一阶
|
|
|
|
|
O(N^3) -> O(N^2)
|
|
|
|
|
O(N^2 * M) -> O(N * M)
|
|
|
|
|
O(N * M^2) -> O(N * M)
|
|
|
|
|
4,四边形不等式有些时候是最优解,有些时候不是
|
|
|
|
|
不是的原因:尝试思路,在根儿上不够好
|
|
|
|
|
|
|
|
|
|
题目:
|
|
|
|
|
|
|
|
|
|
给定一个非负数组arr,长度为N,
|
|
|
|
|
那么有N-1种方案可以把arr切成左右两部分
|
|
|
|
|
每一种方案都有,min{左部分累加和,右部分累加和}
|
|
|
|
|
求这么多方案中,min{左部分累加和,右部分累加和}的最大值是多少?
|
|
|
|
|
整个过程要求时间复杂度O(N)
|
|
|
|
|
|
|
|
|
|
把题目一中提到的,min{左部分累加和,右部分累加和},定义为S(N-1),也就是说:
|
|
|
|
|
S(N-1):在arr[0…N-1]范围上,做最优划分所得到的min{左部分累加和,右部分累加和}的最大值
|
|
|
|
|
现在要求返回一个长度为N的s数组,
|
|
|
|
|
s[i] =在arr[0…i]范围上,做最优划分所得到的min{左部分累加和,右部分累加和}的最大值
|
|
|
|
|
得到整个s数组的过程,做到时间复杂度O(N)
|
|
|
|
|
|
|
|
|
|
摆放着n堆石子。现要将石子有次序地合并成一堆,规定每次只能选相邻的2堆石子合并成新的一堆
|
|
|
|
|
并将新的一堆石子数记为该次合并的得分,求出将n堆石子合并成一堆的最小得分(或最大得分)合并方案
|
|
|
|
|
|
|
|
|
|
给定一个整型数组 arr,数组中的每个值都为正数,表示完成一幅画作需要的时间,再给定一个整数num
|
|
|
|
|
表示画匠的数量,每个画匠只能画连在一起的画作
|
|
|
|
|
所有的画家并行工作,返回完成所有的画作需要的最少时间
|
|
|
|
|
arr=[3,1,4],num=2。
|
|
|
|
|
最好的分配方式为第一个画匠画3和1,所需时间为4
|
|
|
|
|
第二个画匠画4,所需时间为4
|
|
|
|
|
所以返回4
|
|
|
|
|
arr=[1,1,1,4,3],num=3
|
|
|
|
|
最好的分配方式为第一个画匠画前三个1,所需时间为3
|
|
|
|
|
第二个画匠画4,所需时间为4
|
|
|
|
|
第三个画匠画3,所需时间为3
|
|
|
|
|
返回4
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
42 四边形不等式技巧(下)
|
|
|
|
|
|
|
|
|
|
内容:
|
|
|
|
|
|
|
|
|
|
继续熟悉四边形不等式
|
|
|
|
|
|
|
|
|
|
展示好的尝试是最关键的
|
|
|
|
|
|
|
|
|
|
题目:
|
|
|
|
|
|
|
|
|
|
一条直线上有居民点,邮局只能建在居民点上
|
|
|
|
|
给定一个有序正数数组arr,每个值表示 居民点的一维坐标,再给定一个正数 num,表示邮局数量
|
|
|
|
|
选择num个居民点建立num个邮局,使所有的居民点到最近邮局的总距离最短,返回最短的总距离
|
|
|
|
|
arr=[1,2,3,4,5,1000],num=2
|
|
|
|
|
第一个邮局建立在3位置,第二个邮局建立在1000位置
|
|
|
|
|
那么1位置到邮局的距离为2,2位置到邮局距离为1,3位置到邮局的距离为0,4位置到邮局的距离为1,5位置到邮局的距离为2
|
|
|
|
|
1000位置到邮局的距离为0
|
|
|
|
|
这种方案下的总距离为6,其他任何方案的总距离都不会比该方案的总距离更短,所以返回6
|
|
|
|
|
|
|
|
|
|
一座大楼有0~N层,地面算作第0层,最高的一层为第N层
|
|
|
|
|
已知棋子从第0层掉落肯定不会摔碎,从第i层掉落可能会摔碎,也可能不会摔碎(1≤i≤N)
|
|
|
|
|
给定整数N作为楼层数,再给定整数K作为棋子数
|
|
|
|
|
返回如果想找到棋子不会摔碎的最高层数,即使在最差的情况下扔的最少次数
|
|
|
|
|
一次只能扔一个棋子
|
|
|
|
|
N=10,K=1
|
|
|
|
|
返回10
|
|
|
|
|
因为只有1棵棋子,所以不得不从第1层开始一直试到第10层
|
|
|
|
|
在最差的情况下,即第10层是不会摔坏的最高层,最少也要扔10次
|
|
|
|
|
N=3,K=2
|
|
|
|
|
返回2
|
|
|
|
|
先在2层扔1棵棋子,如果碎了试第1层,如果没碎试第3层
|
|
|
|
|
N=105,K=2
|
|
|
|
|
返回14
|
|
|
|
|
第一个棋子先在14层扔,碎了则用仅存的一个棋子试1~13
|
|
|
|
|
若没碎,第一个棋子继续在27层扔,碎了则用仅存的一个棋子试15~26
|
|
|
|
|
若没碎,第一个棋子继续在39层扔,碎了则用仅存的一个棋子试28~38
|
|
|
|
|
若没碎,第一个棋子继续在50层扔,碎了则用仅存的一个棋子试40~49
|
|
|
|
|
若没碎,第一个棋子继续在60层扔,碎了则用仅存的一个棋子试51~59
|
|
|
|
|
若没碎,第一个棋子继续在69层扔,碎了则用仅存的一个棋子试61~68
|
|
|
|
|
若没碎,第一个棋子继续在77层扔,碎了则用仅存的一个棋子试70~76
|
|
|
|
|
若没碎,第一个棋子继续在84层扔,碎了则用仅存的一个棋子试78~83
|
|
|
|
|
若没碎,第一个棋子继续在90层扔,碎了则用仅存的一个棋子试85~89
|
|
|
|
|
若没碎,第一个棋子继续在95层扔,碎了则用仅存的一个棋子试91~94
|
|
|
|
|
若没碎,第一个棋子继续在99层扔,碎了则用仅存的一个棋子试96~98
|
|
|
|
|
若没碎,第一个棋子继续在102层扔,碎了则用仅存的一个棋子试100、101
|
|
|
|
|
若没碎,第一个棋子继续在104层扔,碎了则用仅存的一个棋子试103
|
|
|
|
|
若没碎,第一个棋子继续在105层扔,若到这一步还没碎,那么105便是结果
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
43 状态压缩的动态规划
|
|
|
|
|
|
|
|
|
|
内容:
|
|
|
|
|
|
|
|
|
|
动态规划的状态压缩技巧
|
|
|
|
|
|
|
|
|
|
题目:
|
|
|
|
|
|
|
|
|
|
在"100 game"这个游戏中,两名玩家轮流选择从1到10的任意整数,累计整数和
|
|
|
|
|
先使得累计整数和达到或超过100的玩家,即为胜者,如果我们将游戏规则改为 “玩家不能重复使用整数” 呢?
|
|
|
|
|
例如,两个玩家可以轮流从公共整数池中抽取从1到15的整数(不放回),直到累计整数和 >= 100
|
|
|
|
|
给定一个整数 maxChoosableInteger (整数池中可选择的最大数)和另一个整数 desiredTotal(累计和)
|
|
|
|
|
判断先出手的玩家是否能稳赢(假设两位玩家游戏时都表现最佳)
|
|
|
|
|
你可以假设 maxChoosableInteger 不会大于 20, desiredTotal 不会大于 300。
|
|
|
|
|
Leetcode题目:https://leetcode.com/problems/can-i-win/
|
|
|
|
|
|
|
|
|
|
TSP问题
|
|
|
|
|
有N个城市,任何两个城市之间的都有距离,任何一座城市到自己的距离都为0
|
|
|
|
|
所有点到点的距离都存在一个N*N的二维数组matrix里,也就是整张图由邻接矩阵表示
|
|
|
|
|
现要求一旅行商从k城市出发必须经过每一个城市且只在一个城市逗留一次,最后回到出发的k城
|
|
|
|
|
参数给定一个matrix,给定k。返回总距离最短的路的距离
|
|
|
|
|
|
|
|
|
|
铺砖问题(最优解其实是轮廓线dp,但是这个解法对大厂刷题来说比较难,掌握课上的解法即可)
|
|
|
|
|
你有无限的1*2的砖块,要铺满M*N的区域,
|
|
|
|
|
不同的铺法有多少种?
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
44 DC3生成后缀数组详解
|
|
|
|
|
|
|
|
|
|
内容:
|
|
|
|
|
|
|
|
|
|
后缀数组
|
|
|
|
|
|
|
|
|
|
介绍用DC3算法生成后缀数组的流程
|
|
|
|
|
|
|
|
|
|
题目:
|
|
|
|
|
|
|
|
|
|
给你一个字符串 s,找出它的所有子串并按字典序排列,返回排在最后的那个子串
|
|
|
|
|
Leetcode题目:https://leetcode.com/problems/last-substring-in-lexicographical-order/
|
|
|
|
|
|
|
|
|
|
DC3算法的实现(完全根据论文描述)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
45 后缀数组解决的面试题
|
|
|
|
|
|
|
|
|
|
内容:
|
|
|
|
|
|
|
|
|
|
通过题目进一步熟悉DC3算法
|
|
|
|
|
|
|
|
|
|
通过DC3算法得到height数组
|
|
|
|
|
|
|
|
|
|
题目:
|
|
|
|
|
|
|
|
|
|
给定两个字符串str1和str2,想把str2整体插入到str1中的某个位置,形成最大的字典序,返回字典序最大的结果
|
|
|
|
|
|
|
|
|
|
给两个长度分别为M和N的整型数组nums1和nums2,其中每个值都不大于9,再给定一个正数K。 你可以在nums1和nums2中挑选数字,要求一共挑选K个,并且要从左到右挑。返回所有可能的结果中,代表最大数字的结果
|
|
|
|
|
|
|
|
|
|
最长公共子串问题是面试常见题目之一,假设str1长度N,str2长度M
|
|
|
|
|
一般在面试场上回答出O(N*M)的解法已经是比较优秀了
|
|
|
|
|
因为得到O(N*M)的解法,就已经需要用到动态规划了
|
|
|
|
|
但其实这个问题的最优解是O(N+M),需要用到后缀数组+height数组
|
|
|
|
|
课上将对本题解法代码进行详解
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
46 动态规划猜法中和外部信息简化的相关问题(上)、哈夫曼树
|
|
|
|
|
|
|
|
|
|
内容:
|
|
|
|
|
|
|
|
|
|
以18节做总纲
|
|
|
|
|
|
|
|
|
|
有些动态规划面试题,需要很好的设计参数,这种设计方式都有"外部信息简化"的特征
|
|
|
|
|
|
|
|
|
|
哈夫曼树
|
|
|
|
|
|
|
|
|
|
题目:
|
|
|
|
|
|
|
|
|
|
有n个气球,编号为0到n-1,每个气球上都标有一个数字,这些数字存在数组nums中
|
|
|
|
|
现在要求你戳破所有的气球。戳破第i个气球,你可以获得nums[i - 1] * nums[i] * nums[i + 1] 枚硬币
|
|
|
|
|
这里的i-1和i+1代表和i相邻的、没有被戳爆的!两个气球的序号
|
|
|
|
|
如果i-1或i+1超出了数组的边界,那么就当它是一个数字为1的气球
|
|
|
|
|
求所能获得硬币的最大数量
|
|
|
|
|
Leetcode题目:https://leetcode.com/problems/burst-balloons/
|
|
|
|
|
|
|
|
|
|
给出一些不同颜色的盒子,盒子的颜色由数字表示,即不同的数字表示不同的颜色,你将经过若干轮操作去去掉盒子
|
|
|
|
|
直到所有的盒子都去掉为止,每一轮你可以移除具有相同颜色的连续k个盒子(k >= 1)
|
|
|
|
|
这样一轮之后你将得到 k * k 个积分,当你将所有盒子都去掉之后,求你能获得的最大积分和
|
|
|
|
|
Leetcode题目:https://leetcode.com/problems/remove-boxes/
|
|
|
|
|
|
|
|
|
|
如果一个字符相邻的位置没有相同字符,那么这个位置的字符出现不能被消掉
|
|
|
|
|
比如:"ab",其中a和b都不能被消掉
|
|
|
|
|
如果一个字符相邻的位置有相同字符,就可以一起消掉
|
|
|
|
|
比如:"abbbc",中间一串的b是可以被消掉的,消除之后剩下"ac"
|
|
|
|
|
某些字符如果消掉了,剩下的字符认为重新靠在一起
|
|
|
|
|
给定一个字符串,你可以决定每一步消除的顺序,目标是请尽可能多的消掉字符,返回最少的剩余字符数量
|
|
|
|
|
比如:"aacca", 如果先消掉最左侧的"aa",那么将剩下"cca",然后把"cc"消掉,剩下的"a"将无法再消除,返回1
|
|
|
|
|
但是如果先消掉中间的"cc",那么将剩下"aaa",最后都消掉就一个字符也不剩了,返回0,这才是最优解。
|
|
|
|
|
再比如:"baaccabb",
|
|
|
|
|
如果先消除最左侧的两个a,剩下"bccabb",如果再消除最左侧的两个c,剩下"babb",最后消除最右侧的两个b,剩下"ba"无法再消除,返回2
|
|
|
|
|
而最优策略是:
|
|
|
|
|
如果先消除中间的两个c,剩下"baaabb",如果再消除中间的三个a,剩下"bbb",最后消除三个b,不留下任何字符,返回0,这才是最优解
|
|
|
|
|
|
|
|
|
|
给定一个数组arr,和一个正数M,返回在arr的子数组在长度不超过M的情况下,最大的累加和
|
|
|
|
|
|
|
|
|
|
哈夫曼树的实现
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
47 动态规划猜法中和外部信息简化的相关问题(下)、最大网络流算法之Dinic算法
|
|
|
|
|
|
|
|
|
|
内容:
|
|
|
|
|
|
|
|
|
|
进一步解决带有"外部信息简化"特征的动态规划
|
|
|
|
|
|
|
|
|
|
Dinic算法
|
|
|
|
|
|
|
|
|
|
题目:
|
|
|
|
|
|
|
|
|
|
有台奇怪的打印机有以下两个特殊要求:
|
|
|
|
|
打印机每次只能打印由同一个字符组成的序列。
|
|
|
|
|
每次可以在任意起始和结束位置打印新字符,并且会覆盖掉原来已有的字符。
|
|
|
|
|
给你一个字符串s,你的任务是计算这个打印机打印它需要的最少打印次数。
|
|
|
|
|
Leetcode题目:https://leetcode.com/problems/strange-printer/
|
|
|
|
|
|
|
|
|
|
整型数组arr长度为n(3 <= n <= 10^4),最初每个数字是<=200的正数且满足如下条件:
|
|
|
|
|
1. 0位置的要求:arr[0]<=arr[1]
|
|
|
|
|
2. n-1位置的要求:arr[n-1]<=arr[n-2]
|
|
|
|
|
3. 中间i位置的要求:arr[i]<=max(arr[i-1],arr[i+1])
|
|
|
|
|
但是在arr有些数字丢失了,比如k位置的数字之前是正数,丢失之后k位置的数字为0
|
|
|
|
|
请你根据上述条件,计算可能有多少种不同的arr可以满足以上条件
|
|
|
|
|
比如 [6,0,9] 只有还原成 [6,9,9]满足全部三个条件,所以返回1,即[6,9,9]达标
|
|
|
|
|
|
|
|
|
|
Dinic算法详解
|
|
|
|
|
测试链接:https://lightoj.com/problem/internet-bandwidth
|
|
|
|
|
|
|
|
|
|
|