随笔分类 - algorithm
摘要:看了一下lee215的公众号里关于单调栈的讲解,这里我把用到单调栈和单调队列的常见题总结一下。 单调栈可以维护找左右两侧第一个比它大/小的元素,进而维护以这个元素为最大/小值的最大区间。以单调递增栈为例,一个元素满足进栈条件时,栈顶的元素是它左侧第一个比它小的元素,而令它出栈的是它右侧第一个比它小的
阅读全文
摘要:这里总结一下计算$[1, n]$区间素数的方法。最直接的方式是对区间中的每个数进行枚举,时间复杂度为$O(n\sqrt{n})$,在$n$较大的时候并不好用。这里介绍一下素数筛法,筛法的思路也很直观:对于不超过$n$的每个非负数$p$,删除$2p,3p,4p...$,当处理完所有的数后,最后剩下的就
阅读全文
摘要:列举一些中位数和众数的常见问题和解法 1. 众数 一个长度为$N$的列表,出现次数大于$\left \lfloor N/2 \right \rfloor$的数为这个列表的众数。 1.1 摩尔投票算法 摩尔投票算法(Boyer-Moore majority vote algorithm)的思路类似一个
阅读全文
摘要:区间问题,例如区间求和、区间最值,有很多数据结构可以选择。稀疏表、树状数组和线段树就是解决区间问题比较套路的方法,只要理解了这些数据结构的特征并且掌握了代码模版,遇到可建模成区间求和和区间最值的问题,就可以轻松解决了。 1. 稀疏表(Sparse Table) 稀疏表经常用来处理离线多轮RMQ(区间
阅读全文
摘要:1. 单模匹配 1.1 KMP(Knuth-Morris-Pratt) 1 from typing import List 2 3 4 class KMP: 5 def _next(self, pattern: str) -> List[int]: 6 """ 7 计算next数组 8 """ 9
阅读全文
摘要:最长上升子序列(LIS)和最长公共子序列(LCS)是DP算法里比较经典的问题了。今天来说说这两个问题的解法,包括常规的动态规划解法,还有一些拓展性的解法。 1. LIS 1.1 LIS长度(Leetcode 300) 1.1.1 动态规划解法 DP问题的最大难点就是选择子问题,子问题选对了,状态转移
阅读全文
摘要:今天刷leetcode的时候做了好几道和二分搜索(BS)相关的题,发现主要的问题有两个:有的题不是很直观的就知道用BS;BS用起来corner case处理不好。下面我就来总结一下BS的用法和代码模版。 1. 什么时候可以用BS算法? 这里先引用下大牛Knuth的话——“Although the b
阅读全文