分享|盘点 LC 周赛常见且需要掌握的套路(附题单)
5992
2024.02.23
2026.01.01
发布于 未知归属地

很多朋友打周赛可能经常遇到这种情况,某个题目在开赛很短时间之内就有大量通过,但自己却毫无思路只能坐牢,而赛后也发现正解是不看题解不可能独立完成的,于是怀疑自己的智商。事实上这往往是因为题目的套路性很强(LC和OJ不同,OJ重思维,LC重知识点和套路),只要做过就不难举一反N,但第一次遇到确实很大概率想不到。本贴盘点10个LC常考的套路,每个主套路或子套路的题目已经按照题主认为的难度按从易到难排序~

套路1:二分猜答案

这是LC上相当常见,CF等OJ也经常出现的。很多题目你拿到时会发现正面解决问题似乎做不到,但如果换一个角度,给定一个结果,验证其能不能满足题意却比较容易实现。而同时还不难发现答案具有单调性(例如x满足题意,x+1必定也满足题意,所以找到最小的x一定就是答案)。这时就可以用“二分猜答案”。即先确定答案的值域,再写一个验证方法(即给定x后,以合理的复杂度判断能否满足题意),然后在此值域上二分查找最小或最大满足要求的值。一般来说,如果涉及追求“最大值最小”或“最小值最大”,二分答案往往是最好的选择。

875.爱吃香蕉的珂珂

这是该套路最裸的题目,由于取整很棘手,直接计算最优速度是几乎不可能的。但给定一个速度验证能不能吃完却只需简单遍历数组。

其他该套路的题目:
1482.制作m束花的最少天数 难度分1945
3639.变为活跃状态的最小时间 难度分1853
3281.范围内整数的最大得分 难度分1768
2560.打家劫舍4 难度分2081
1231.分享巧克力 难度分2029
1970.你能穿过矩阵的最后一天 难度分2123,预处理+BFS/DFS验证,有不用二分的做法(1631,2812题是类似情况)
3710.最大划分因子 难度分2135,二分猜答案+染色法判断二分图
2604.吃掉所有谷子的最短时间 会员题
3733. 完成所有送货任务的最少时间 难度分1973,非二分做法可能不止Medium
3620.恢复网络路径 难度分1998,二分猜答案+DP验证
1898.可移除字符的最大数目 难度分1912,CF上居然有1700
3600.升级后最大生成树稳定性 难度分2301,二分猜答案+反向kruskal,有不二分的做法
3464.正方形上的点之间的最大距离 难度分2806,看似吓人,实际二分套二分的做法很容易通过,和同场第三题难度分换一下更合理
2819.购买巧克力后的最小相对损失 会员题,做法很多,二分猜答案正确性很反直觉
3344.最大尺寸数组 会员题,验证需要位运算技巧,当然如果知道答案最大只有1196,那还是有不少较粗暴的做法能过
2234.花园的最大总美丽值 难度分2561,不难看出有必要二分猜答案,但有一处思维盲点,如果没想到,用二分的总复杂度反而不如暴力
2071.你可以安排的最多任务数目 难度分2648,直接贪心找不到嗑药时机,但二分猜答案+贪心验证可以
3145.大数组元素乘积 难度分2859,思维角度不太难,比赛的1.5小时内给出正确实现确实很难
3357. 最小化相邻元素的最大差值 难度分3077,验证方法很难想,易错细节也很多
3049.标记所有下标的最早秒数2 难度分3111,验证方法用到反悔堆,相当难想

注意如果答案不满足单调性,就有可能需要找其他的方法。
2809.使数组和小于等于x的最短时间 难度分2979,这道题二分不是[不必要]而是[不正确],因为这是个夜长梦多的事,t秒能做到不见得t+1秒也能,答案不满足单调性。

2468.根据限制分割消息 难度分2382,这道题答案确实不满足单调性,但也确实可以(但不是必须)二分猜答案。因为答案是“分段单调”,可以先从9,99,999和9999里找一个最小的能过的,在确定答案的位数之后再二分。

另外即使答案满足单调性,正解也未必是二分,毕竟二分猜答案很多时候作为没办法的办法,需要验证的次数和答案范围成对数关系,一般会带来额外复杂度。
3350.检测相邻递增子数组2 难度分1600,这道题还有个简单版,就是实现一个check方法,官方这么出题实在不知道该说什么了……实际上DP过程中就能实时更新答案(注意不要漏掉一条序列拆两半的情况),不需要二分。

套路1.5:二分猜答案解决第k大/第k小问题

第k大/第k小问题最简单的解决方法是排序。但有时整个数组(矩阵)元素过多,不能直接列出,更何谈排序。因此要换个方法,即转化为给定m验证小于等于m的有没有k个,最小的答案是“有”的m,那就是第k小的元素。

719.找出第k小的数对距离 年代久远难度分未知
786.第k小的素数分数 难度分2168
1201.丑数3 难度分2039,二分猜答案+三数容斥,验证时算n以内有多少丑数
2040.两个有序数组的第k小乘积 难度分2517
3134.找出唯一性数组的中位数 难度分2451,思维转换+哈希表统计种类,略抽象

套路2:前缀和哈希表

长度为n的子数组总量是n^2级别,因此子数组计数问题一般不能二重循环。常见的做法是边算前缀和,边用哈希表统计前缀和结果的出现次数,累加答案时注意先查后插。这个套路有个极其易错的细节,空数组的前缀和为0,哈希表的初值往往应该是{0:1}而不是空表。

560.和为k的子数组 裸题,必须掌握
525.连续数组 先把0转成-1,然后就是裸题。1983题情况类似
1590.使数组和能被p整除 难度分2038,卡点在负数取模,2845题也是一样的情况
3755.最大平衡异或子数组的长度 难度分1663
2488.统计中位数为k的子数组 难度分1998
1124.表现良好的最长时间段 难度分1908,正确性证明要想一下(这题干,这示例,真的扎心)
3026.最大的好子数组和 难度分1816,哈希表值是什么需要认真思考
3728. 边界与内部和相等的稳定子数组 难度分1909,部分写法需要特判所有[0,0]位置
3729. 统计有序数组中可被 K 整除的子数组数量 难度分2248
2025.分割数组的最多方案数 难度分2217
2949.统计美丽子字符串2 难度分2444,把平方去掉需要一点数论基础
3714.最长的平衡子串2 难度分2202,哈希表需要存相对复杂的状态

套路2.5:前缀和哈希表解决奇偶性问题

前缀和除了求和外,也适用位运算中的异或运算,区间[l,r]的异或和可以表示成xorpre[r]⊕xorpre[l-1]。有些题目关心每个字符出现的奇偶性,但不关心具体次数,这可以用k位二进制数做掩码,表示k种字符的奇偶性。字符c每出现一次,对应c的位的奇偶性就会改变,而遍历整个串过程对掩码求前缀和并使用前缀和哈希表套路,就能求出满足特定奇偶性的区间总数量。

1371.每个元音包含偶数次的最长子字符串 难度分2040
1915.最美子字符串的数目 难度分2234
2791.树中可以形成回文的路径数 难度分2677,位运算性质与树结构相结合

套路3:差分前缀和

差分数组一般用来解决区间问题。更新区间时,给差分数组的下标l加1并给下标r+1减1(假如r+1有意义),就等同于给真实值下标在[l,r]这个区间的所有元素都加1。对差分数组求前缀和就得到真实值。LC上这类题目包括一维差分和二维差分,后者无论思维难度如何,可直接标Hard。

一维:
2406.将区间分为最少组数 难度分1713,差分前缀和也许不是最优解,但这道题可以让你快速认识这个套路
2381.字母移位2 难度分1793
1943.描述绘画结果 难度分1969
2251.花期内花的数目 难度分2022,注意要用离散化来避免差分数组开的过大导致MLE
3356.零数组变换2 难度分1913,二分猜答案+差分前缀和
798.得分最高的最小轮调 难度分2129
3279.最大活塞总面积 会员题
2528.最大化城市的最小电量 难度分2235,二分猜答案+滑动窗口/差分数组验证,差分数组做法较抽象
3362.零数组变换3 难度分2424,贪心+优先队列+差分前缀和
3009.折线图上的最大交点数量 会员题,想想需要特判什么情况

二维:
2536.子矩阵元素加1 难度分1583(比赛期间放过了纯暴力与一维前缀和,实际约2000),考察二维差分的实现
2132.用邮票贴满网格图 难度分2364

套路4:单调栈贡献法

贡献法常用于解决类似“所有子数组的最小/最大值”问题,即用单调栈求出每个元素做了多少次最小/最大。单调栈属于进阶技巧,这类题目如没见过很大概率会坐牢,一般建议标Hard。

907.子数组的最小值之和 难度分1975,裸题
1856.子数组最小乘积的最大值 难度分2051
1950.所有子数组最小值中的最大值 会员题
3359. 查找最大元素不超过 K 的有序子矩阵 会员题
2818.操作使得分最大 难度分2396,全站第一融合怪,涉及单调栈,排序贪心,快速幂,素因数分解,细节很多
2281.巫师的总力量和 难度分2621,单调栈贡献法+前缀和的前缀和/特殊前缀和

套路5:枚举子序列逐个验证

有些题目虽然作为第三或第四题,但数据范围极其小,只要枚举每个元素“选或不选”的所有可能性,换句话说枚举所有子序列,然后逐一验证就能通过。往往回溯法和二进制枚举都能通过(后者能过前者一定也能过,反之不成立,如2597题暴力法)。这类题目有时考察其他知识点。

2151.基于陈述统计最多好人数
这道题看似难以分析,且不说可能情况是否唯一,即使唯一,写一个程序来模拟人类做这类逻辑推理题的过程也几乎做不到。但看看数据范围,枚举每个人是好是坏的所有情况逐个验证,就轻松通过了。这道题难度分1980,但如果不标Hard迷惑人,1400都嫌多。捎带提一下,新朋友可以看看这场周赛前三题,你会震惊的。

3566.等积子集的划分方案 难度分1459,迷惑思路不少,还是比上面那个"Hard"难的
2397.被列覆盖的最多行数 难度分1718,本质是枚举组合,建议回溯
2212.射箭比赛的最大得分 难度分1868,有思维转换,而且多余的箭怎么处理这是个问题,值了
1617.统计子树中城市之间最大距离 难度分2308,枚举+BFS
2959.关闭分布的可行集合数目 难度分2077,枚举+floyd最短路
3116.单面值组合的第K小金额 难度分2387,套路1.5中1201题进阶版,涉及15数容斥,需要枚举子集

这里再分享一例使用二进制枚举法,解决桥牌中一个看似棘手的问题:
桥牌单手与联手大牌点概率

套路6:值域脑筋急转弯

有些题目看起来难找突破口或者解法极其复杂,但特定要素给了反常的很小值域,这时就需要尝试暴力枚举这个要素的所有值,或者用其他从值域入手的做法。

2857.统计距离为k的点对 难度分2081,看似难以解决,但可以暴力枚举k的所有拆分,就可用位运算性质直接定位
2198.单因数三元组 会员题,值域上3个for循环就过了
3717. 使数组变美的最小操作次数 会员题,贪心肯定是不对的,但这道题肯定是能做的,看看原数组max最大才多少
2653.滑动子数组的美丽值 难度分1785,每滑动一步都可以枚举整个值域计数
1766.互质树 难度分2231,节点值范围太小,遍历时可以带上所有可能得节点值的信息
2250.统计包含每个点的矩形数目 难度分1997,同场第四题的二维版,但看看x和y如此不对称的范围,就应该知道怎么照搬第四题的做法了
1906.查询差绝对值的最小值 难度分2146,CF标3100的题目绝对不可能不做任何削弱就出在LC周赛,所以认真看看数据范围吧,你会发现可以用本贴的套路2来解决

套路7:中位数贪心

中位数贪心指给定一排点,想找一个点让所有点离这个点距离总和最近,那么就应该选这些点坐标的中位数,而不是平均数,因为如果用平均数,就会导致多数点为极个别的极端值做牺牲。如果是偶数个点,则最中间的2个点之间的任意点都是最优的。对二维情况下的曼哈顿距离同样适用。

462.最小操作次数使数组元素相等2 一维裸题
296.最佳的碰头地点 二维裸题
2033.获取单值网格的最小操作次数 难度分1671,二维输入实则一维问题
2607.使子数组元素和相等 难度分2071
1478.安排邮筒 难度分2190,记忆化搜索/区间DP+中位数贪心
2448.使数组相等的最小开销 难度分2005,如果误认为最终值有可能不会在原数组中,那就等着被卡常卡到比赛结束吧
2968.执行操作使频率分数最大 难度分2444
3086.拾起K个1需要的最少行动次数 难度分2672,可能还需要本贴套路1
3441.变成好标题的最少代价 难度分2765,中位数贪心+划分型DP,如果用其他做法则优化要求较高
3762.使数组元素相等的最小操作次数 难度分2497,中位数贪心+ zhu xi 树,面试角度极严重超纲

套路8:筛法预处理素数

有的题目涉及统计一个区间内的素数总量,或者需要验证大量整数是否为素数,如果O(n^0.5)暴力判断区间内的每个数,复杂度不可接受。这时需要用筛法把题目数据范围内的所有素数都预处理出来。筛法包括埃氏筛和线性筛,后者在LC上一般视为超纲。注意LC平台看的是所有case总时间,而且每个case都会构造一个解题类,因此要让第一个testcase输入之前,预处理部分能先被运行。

204.计数质数 裸题
2523.范围内最接近的两个质数 难度分1649
2761.和等于目标值的质数对 难度分1504
3233.统计不是特殊数字的数字数量 难度分1509
3770.可表示为连续质数和的最大质数 难度分1547
3629.通过质数传送到达终点的最少跳跃次数 难度分2139,最好还是埃氏筛先筛一遍吧,不然你想见一个元素判断一个吗
3589.计算质数间隔平衡子数组 难度分2235,预处理+滑动窗口+数据结构
2867.统计树中的合法路径数目 难度分2428,预处理+树形DP

但如果暴力判断素数的复杂度可以接受,预处理可能会弄巧成拙。

3044.出现频率最高的质数 难度分1737,这道题构造一个存在很多不重复的大素数或是验证耗时很长的大合数(如966289,974153必须验证到最后或接近最后才发现不是素数)的6*6矩阵非常困难,应该不是LCUS官方能力范围内的。而预处理需要大量时间,根本回不了本。

3765.完全质数
难度分1378,以题目给的数据范围预处理是绝对不可能的,所以最好的办法就是别被Medium标签骗了,直接暴力验证。你可以猜一猜茫茫数海里有几个素数满足如此苛刻的题目条件,return False提交一下就知道你猜的偏差多少了。(你也可以在正确代码之前加一个if num>10000: return False,就知道为什么暴力也能轻松过了

套路9:异或字典树

有一类位运算题目,需要多次求与给定元素做异或后值最大的元素(或异或值),如果每次都遍历,复杂度会不可接受。这时就要用到0-1字典树,即每个节点的值为0或1,且所有叶子节点的深度相同。由于想要异或最大,就需要每一位都尽量和target不一样,而且总是高位优先。所以搜索字典树时要从高位到低位,并尽量走和当前位和target不一样的子树。异或字典树必须保证每位对齐才有意义,所以对于较小的数,必须给高位补足够的0。

421.数组中两个数的最大异或值 裸题
1938.查询最大基因差 难度分2502
1803.统计异或值在范围内的数对 难度分2479,字典树需要有实时获取节点计数功能
2479.两个不重叠子树的最大异或值 会员题,前序查询后序插入就保证不重叠了
2935.找出强数对的最大异或值2 难度分2348,字典树需要有删除功能
3632. 异或至少为 K 的子数组数目 会员题,前缀异或+字典树

套路10:子数组与或性质

有些和子数组位运算相关的题目,暴力做的复杂度似乎是O(n^2)的,看似无法优化,拆位也拆不出来。实际上当子数组的起点(或终点)固定时,可能的与/或值的数量相当有限。因为与运算1只能越来越少,或运算1只能越来越多。设起点值为1010101,子数组与值最多有5个(例如1010101,1000101,1000001,1,0这已经是最长),子数组或值最多有4个。因此如果内循环不用for遍历所有下标而是枚举可能的值,总复杂度就不是O(n^2)而是O(nlogU)。

898.子数组按位或操作 难度分2133
1521.找到最接近目标值的函数值 难度分2383(被同场第三题抬上去的)
3209.子数组按位与值为K的数目 难度分2050
3117.划分数组得到最小的值之和 难度分2735,官方没想到位运算性质误以为需要线段树/单调队列之类,参赛的也很多不敢交暴力,导致极其离谱的难度分

评论 (16)