
思维
csu_xiji
这个作者很懒,什么都没留下…
展开
-
力扣 240. 搜索二维矩阵 II 二分
https://leetcode-cn.com/problems/search-a-2d-matrix-ii/思路:做法太多了,最简单的暴力,复杂度O(nm)O(nm)O(nm),或者依次考虑每行/每列,然后二分判断,复杂度O(nlgm)O(nlgm)O(nlgm)或者O(mlgn)O(mlgn)O(mlgn)。这里就说一下最巧妙的O(n+m)O(n+m)O(n+m)的做法,考虑以矩形右上角为起始点,那么我们可以比较matrixx,ymatrix_{x,y}matrixx,y与targettarget原创 2021-10-26 23:52:56 · 427 阅读 · 0 评论 -
力扣 229. 求众数 II 思维
https://leetcode-cn.com/problems/majority-element-ii/思路:哈希解法就不多说了,没啥意思。说一下进阶的算法,其实之前做过类似的,不过是求出现超过n/2次的元素,核心思想就是成对消耗:每次选取2个不同的元素从数组中删去,那么最后剩下的元素就是可能的答案。证明略,显然这个结论在此题依然成立,那么直接模拟就行。看了官方题解才知道这是摩尔投票法。class Solution {public: vector<int> majorityEl原创 2021-10-23 01:51:25 · 757 阅读 · 0 评论 -
力扣 2025. 分割数组的最多方案数 前缀和+哈希
https://leetcode-cn.com/problems/maximum-number-of-ways-to-partition-an-array/思路:第一次在比赛中间干掉hardhardhard题,纪念一下。先计算出前缀和数组sumsumsum,并设整个数组的总和为tottottot,那么问题中的条件就等效于在前缀和数组中寻找sumi=tot−sumisum_i=tot-sum_{i}sumi=tot−sumi的iii的个数,也即sumi=tot/2sum_i=tot/2sumi=to原创 2021-10-04 23:18:51 · 254 阅读 · 0 评论 -
力扣 470. 用 Rand7() 实现 Rand10() 思维
https://leetcode-cn.com/problems/implement-rand10-using-rand7/思路:有意思的题目。直接用加法、乘法、取模得到的结果是不对的,原因是通过运算得到的结果可能有多种组合形式,就拿加法而言,2=1+12=1+12=1+1,但是3=1+2=2+13=1+2=2+13=1+2=2+1,显然每个数字出现的概率是不一样的,当然我们可以使用出现概率相同的数字来计算,这样也可以保证正确性。不过还有一种更加简单的方法,我们认为每次随机取得的数都是独立的,那么经过两原创 2021-09-06 00:58:49 · 184 阅读 · 0 评论 -
力扣 789. 逃脱阻碍者 思维
https://leetcode-cn.com/problems/escape-the-ghosts/思路:一开始居然还傻乎乎的写了bfsbfsbfs,其实就是思维类题目。显然无论是你还是阻碍者,到达目标点的距离即二者之间的曼哈顿距离,那么只要有一个阻碍者到终点的距离<=<=<=你到终点的距离,一定不可能逃脱成功,否则可以逃脱成功。class Solution {public: using pr=pair<int,int>; int calDis(in原创 2021-08-29 02:01:02 · 158 阅读 · 0 评论 -
力扣 5835. 最大方阵和 思维+贪心
https://leetcode-cn.com/problems/maximum-matrix-sum/思路:可恶啊,居然被这道题卡了。对于矩阵中任意两个坐标,我们可以找到一条从起始坐标到终止坐标的路径,那么对这条路径上所有相邻点做一次操作,最后的结果就是起始位置和终止位置的值取反,其余值不变。想到这一点就比较好做了,我们可以使用这种方式让所有的负数成对内耗掉,根据贪心想法自然要从小到大开始。需要注意的一点是如果负数的个数是奇数个,那么最终会剩下一个最大的负数没有被消耗掉。此时我们有两种选择:不做任原创 2021-08-22 00:28:08 · 142 阅读 · 0 评论 -
力扣 233. 数字 1 的个数 数学 计数
https://leetcode-cn.com/problems/number-of-digit-one/思路:答案就是nnn的每一位(个位、十位、百位…)上出现的1的数量的总和。那么对于任意一个数字abcdeabcdeabcde,假设计算ccc位上的1,且有high=ab,cur=c,low=de,digit=102high=ab,cur=c,low=de,digit=10^2high=ab,cur=c,low=de,digit=102,现在开始分类讨论ccc的取值:c=0c=0c=0,为了让这一原创 2021-08-14 01:46:22 · 148 阅读 · 0 评论 -
力扣 446. 等差数列划分 II - 子序列 dp
https://leetcode-cn.com/problems/arithmetic-slices-ii-subsequence/思路:就知道是dp,但是差一步没写出来,唉。考虑用dp[i][j]dp[i][j]dp[i][j]表示以nums[i]nums[i]nums[i]结尾公差为jjj的长度>=2>=2>=2的子序列个数。那么可以枚举等差数列的最后两项:numsj、numsinums_j、nums_inumsj、numsi。计算其公差dis=numsi−numsjdis=n原创 2021-08-11 01:46:27 · 172 阅读 · 0 评论 -
力扣 413. 等差数列划分 数学 双指针
https://leetcode-cn.com/problems/arithmetic-slices/思路:显然可以通过双指针找到等差数列的区间[l,r][l,r][l,r],那么依据题目的定义,分别统计长度为3、4、5...3、4、5...3、4、5...的等差数列的个数即可,即:(r−l−2)+(r−l−3)+...+1(r-l-2)+(r-l-3)+...+1(r−l−2)+(r−l−3)+...+1。这不就是等差数列的和嘛,可以O(1)O(1)O(1)求得,因此算法的总复杂度为O(n)O(n)O原创 2021-08-11 00:30:00 · 130 阅读 · 0 评论 -
力扣 457. 环形数组是否存在循环 思维
https://leetcode-cn.com/problems/circular-array-loop/思路:用一个数组标记iii是否走过,然后对每个位置做一次循环模拟即可。但是这样复杂度是O(n2)O(n^2)O(n2)的,事实上,对于上次遍历过的点,如果没有找到答案,那么这些点都是无解的,我们可以把它们剔除掉,这样可以把时间复杂度降低到O(n)O(n)O(n)。不过为了区分上次遍历和当前遍历,需要新开一个数组。class Solution {public: bool circularA原创 2021-08-08 01:19:08 · 159 阅读 · 0 评论 -
力扣 581. 最短无序连续子数组 思维
https://leetcode-cn.com/problems/shortest-unsorted-continuous-subarray/思路一:可以把原数组分为三部分:a、b、ca、b、ca、b、c,其中a、ca、ca、c满足题意,是升序排序的,但是bbb不满足题意。考虑对序列进行排序,排序后的序列必然也是以aaa开头ccc结尾的,减去这两部分即为bbb。class Solution {public: int findUnsortedSubarray(vector<int>原创 2021-08-04 00:48:33 · 97 阅读 · 0 评论 -
力扣 1743. 从相邻元素对还原数组 思维 图
https://leetcode-cn.com/problems/restore-the-array-from-adjacent-pairs/思路:很简单,因为元素不重复,所以仅出现一次的元素要么在首要么在尾,随便选取一个当作起始节点,每一对数对当作一条边,在图上跑一遍即可。class Solution {public: vector<int> restoreArray(vector<vector<int>>& adjacentPairs) {原创 2021-07-25 19:25:33 · 132 阅读 · 0 评论 -
力扣 4. 寻找两个正序数组的中位数 二分
https://leetcode-cn.com/problems/median-of-two-sorted-arrays/思路一:双指针O(n)O(n)O(n)合并两个有序数组。class Solution {public: double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) { int n=nums1.size(); int m=nums2.siz原创 2021-07-18 12:47:51 · 160 阅读 · 0 评论 -
力扣 面试题 17.10. 主要元素 思维/哈希
https://leetcode-cn.com/problems/find-majority-element-lcci/思路:哈希可以直接做,但是空间复杂度是O(n)O(n)O(n)的。为了降低空间复杂度至O(1)O(1)O(1),我们可以使用Boyer-Moore投票算法(力扣官方题解),其核心思想是:在每一轮投票过程中,从数组中删除两个不同的元素,直到投票过程无法继续,此时数组为空或者数组中剩下的元素都相等。如果数组为空,则数组中不存在主要元素;如果数组中剩下的元素都相等,则数组中剩下的元素可原创 2021-07-09 16:14:09 · 103 阅读 · 0 评论 -
力扣 815. 公交路线 多源多汇bfs 思维
https://leetcode-cn.com/problems/bus-routes/思路一:首先看数据范围,暴力连边的话肯定是不行滴,因为车站的数量可能达到10610^6106。考虑转换一下思路,把一条公交路线抽象为一个点,那么任意两条有公共点的公交线路之间有一条边权为1的边,这样我们可以得到一张图,在这个图上做bfsbfsbfs即可,注意此时是多源多汇的bfs。class Solution {public: int numBusesToDestination(vector<vec原创 2021-06-29 12:47:17 · 285 阅读 · 0 评论 -
力扣 5770. 反转表达式值的最少操作次数 中缀表达式计算 树形dp
https://leetcode-cn.com/problems/minimum-cost-to-change-the-final-value-of-expression/思路:表达式问题做少了……看到给定的输入,显然是一个中缀表达式。如果显示建立出一棵对应的树,并用dp[i][j]dp[i][j]dp[i][j]表示把节点iii及其子树所代表的表达式的值修改为jjj所需要的最少操作次数,那么这就是一个树形dpdpdp问题。中缀表达式的性质在此不多赘述,假设已知两个节点a、ba、ba、b,那么当操作符号原创 2021-06-13 16:30:14 · 170 阅读 · 0 评论 -
力扣 5778. 使二进制字符串字符交替的最少反转次数 思维 规律
https://leetcode-cn.com/problems/minimum-number-of-flips-to-make-the-binary-string-alternating/思路:dpdpdp的做法可以看官方题解……这边说一下我的思路,感觉想的有点歪。首先可以认为原始字符串由若干个交替字符串拼接而成,那么我们先找到这些交替字符串,然后把所有奇数或者所有偶数位置的交替字符串全部翻转,即可把它们全部拼接起来。因此最少操作要么在奇数位置产生,要么在偶数位置产生。但是这样我们只使用了操作2,没有原创 2021-06-06 17:21:32 · 348 阅读 · 0 评论 -
力扣 1744. 你能在你最喜欢的那天吃到你最喜欢的糖果吗? 思维
https://leetcode-cn.com/problems/can-you-eat-your-favorite-candy-on-your-favorite-day/思路:对于第iii个询问,可以求出第favoriteTypeifavoriteType_ifavoriteTypei类糖果的区间,然后根据每天最多吃的糖果数量和最少吃的糖果数量可以求出第favoriteDayifavoriteDay_ifavoriteDayi天能吃的糖果数量区间,判断他们之间是否有交集即可。class Solu原创 2021-06-02 02:07:33 · 185 阅读 · 0 评论 -
力扣 554. 砖墙 哈希 思维
https://leetcode-cn.com/problems/brick-wall/思路:很容易证明,最优解的那条线至少穿过了一对砖块之间的缝隙。也就是说,最优解一定在缝隙处产生。那么我们可以计算每个缝隙处的砖块数量,并记录最大值,答案就等于墙的个数减去该最大值。class Solution {public: int leastBricks(vector<vector<int>>& wall) { unordered_map<unsi原创 2021-05-02 02:18:30 · 146 阅读 · 0 评论 -
力扣 897. 递增顺序搜索树 中序遍历 思维
https://leetcode-cn.com/problems/increasing-order-search-tree/思路:最简单的方法就是用数组存储中序遍历的结果,再按照要求重建。这种做法没什么意思,我们看一下原地修改的算法。我们可以用preprepre记录中序遍历中当前节点的上一节点,在处理完左子树后,preprepre指向左子树的最右节点,需要令pre.right=cur,cur.left=nullpre.right=cur,cur.left=nullpre.right=cur,cur.le原创 2021-04-25 01:42:21 · 148 阅读 · 0 评论 -
力扣 363. 矩形区域不超过 K 的最大数值和 思维 set
https://leetcode-cn.com/problems/max-sum-of-rectangle-no-larger-than-k/思路:暴力枚举的话是O(n2m2)O(n^2m^2)O(n2m2)的,肯定过不了。考虑枚举左右边界l、rl、rl、r,然后计算a[i]=∑j=lrmatrix[i][j]a[i]=\sum_{j=l}^{r}matrix[i][j]a[i]=∑j=lrmatrix[i][j],那么问题就转换为:在长度为nnn的数组aaa中,找到一个区间s、ts、ts、t,使得a原创 2021-04-22 20:12:53 · 133 阅读 · 0 评论 -
力扣 220. 存在重复元素 III 思维 set
https://leetcode-cn.com/problems/contains-duplicate-iii/思路一:abs(i−j)<=kabs(i-j)<=kabs(i−j)<=k很容易做到,只要我们按照区间处理元素即可。现在考虑第一个条件,如果我们保证元素有序(从小到大),那么只要任意两个相邻元素之差<=t<=t<=t即可。不难想到用setsetset维护。class Solution {private: set<int> s;原创 2021-04-17 02:18:24 · 243 阅读 · 0 评论 -
力扣 87. 扰乱字符串 记忆化搜索 思维
https://leetcode-cn.com/problems/scramble-string/思路:先定义一种字符串之间的相似运算:如果字符串a、b长度相等且含有的字符都相同,我们认为a和b相似。显然如果s、t互为扰乱字符串,则它们一定相似。从扰乱字符串的规则可以发现,如果断点是i,那么至少满足以下两种情况的某一种:s[0…i]、t[0…i]s[0…i]、t[0…i]s[0…i]、t[0…i]相似且s[i+1…n)、t[i+1…n)s[i+1…n)、t[i+1…n)s[i+1…n)、t[i+1…原创 2021-04-17 01:29:29 · 154 阅读 · 0 评论 -
力扣 73. 矩阵置零 思维
https://leetcode-cn.com/problems/set-matrix-zeroes/思路:用一个变量记录第一列是否有0,然后就可以把数组的第一行和第一列作为标记位了。如果m[i][j]=0m[i][j]=0m[i][j]=0,就令m[i][0]=m[0][j]=0m[i][0]=m[0][j]=0m[i][0]=m[0][j]=0,标记第iii行、第iii列需要置为零。最后更新的时候要倒着来或者从第二行开始,因为第一行被用作标记位了,在处理完其它数据之前不能更新,不然可能会有问题,举例原创 2021-03-21 02:10:01 · 241 阅读 · 0 评论 -
力扣 331. 验证二叉树的前序序列化 思维
https://leetcode-cn.com/problems/verify-preorder-serialization-of-a-binary-tree/思路:最直观的方法就是把树重构出来,然后进行判断。这里说一下不需要重构的方法,考虑用一栈维护当前所有已知节点的还需要填充的儿子数量,那么如果遇到了#\##,直接把栈顶值减一即可;如果遇到了非空节点,仍要把栈顶值减一,然后再压入一个2(新节点还有两个儿子节点待补充);如果栈顶为空,那么直接丢掉即可。在字符串还未遍历完时栈已经为空,说明无解(未用完给原创 2021-03-12 01:25:12 · 127 阅读 · 0 评论 -
PIPIOJ 1485: PIPI的位运算问题Ⅳ 位运算
http://pipioj.online/problem.php?id=1485思路:核心思想就是把输入转为二进制表示,然后分别考虑每一位的贡献。我们可以用sumisum_isumi表示输入数据流中二进制表示第iii位1的总和,那么在读入第i个数据时,此时sumsumsum数组记录的就是前i-1个数据的信息,那么单独考虑第i个数据的每一位,我们可以轻松的得到前i-1个数据中在这一位上和它相等或不等的个数,根据异或性质累加即可。#include<bits/stdc++.h>#define原创 2021-03-09 14:44:51 · 317 阅读 · 0 评论 -
PIPIOJ 1439: PIPI的位运算问题Ⅱ 位运算 异或和
http://pipioj.online/problem.php?id=1439思路:如果我们能够快速计算出[0,n][0,n][0,n]内所有数的二进制第iii位(假设从低位开始,下标从1开始)上111的总和,那么依据前缀和的性质就可以在O(1)O(1)O(1)时间内得到[L,R][L,R][L,R]内所有数的二进制第iii位上111的总和,依据异或的性质我们知道,如果总和是奇数,那么这一位为111否则为000。那么如何快速计算总和呢?我们写下前八个数的二进制表示:000、001、010、011、10原创 2021-03-07 02:13:47 · 248 阅读 · 0 评论 -
PIPIOJ 1475: PIPI打怪Ⅲ 单调栈 思维
http://pipioj.online/problem.php?id=1475思路:对于任意一个数aia_iai,若我们知道在它左侧的第一个小于它的数ala_lal,在它右侧的第一个小于它的数ara_rar,那么当区间被限制到(l,r)(l,r)(l,r)内且包含aia_iai时,这个区间的最小值一定是aia_iai。不妨设ansjans_jansj表示区间长度为jjj时的最大价值,那么显然我们要做一个更新操作:ansj=max(ansj,ai),1<=j<=r−l−1ans_原创 2021-03-06 18:14:58 · 270 阅读 · 2 评论 -
PIPIOJ 1413: 士兵排阵Ⅲ 带权中位数问题
http://pipioj.online/problem.php?id=1413思路:带权中位数问题,详细证明参见百度百科。先给出结论:∑i=1n∣xi−x∣∗wi\sum_{i=1}^{n}|x_i-x|*w_i∑i=1n∣xi−x∣∗wi的最小值当且仅当x=x(∑i=1nwi)/2x=x_{(\sum_{i=1}^nw_i)/2}x=x(∑i=1nwi)/2(此处不细致考虑下标问题)时取得。这里给出我自己的理解(非严谨证明),我们知道∑i=1n∣xi−x∣\sum_{i=1}^{n}|x原创 2021-03-06 17:28:17 · 187 阅读 · 3 评论 -
PIPIOJ 1018: 士兵排阵 贪心 数学
http://pipioj.online/problem.php?id=1018思路:和这道题很像。既然已知当x=a[mid]x=a[mid]x=a[mid]时,∑i=1n∣ai−x∣\sum_{i=1}^n|a_i-x|∑i=1n∣ai−x∣取得最小值,那么将所有士兵移动到同一行的纵坐标就确定了。现在考虑横坐标,假设最终结果中第一个士兵的横坐标为ttt,那么根据贪心策略,我们肯定希望最小的xix_ixi移动到ttt,第二小的xix_ixi移动到t+1t+1t+1……那么对横坐标进行排序后,我们原创 2021-03-06 01:57:58 · 393 阅读 · 0 评论 -
CSUOJ 2323 疯狂的企鹅II 贪心 思维
http://acm.csu.edu.cn:20080/csuoj/problemset/problem?pid=2323思路:首先明确一点,行和列可以分开计算,没有影响。先考虑把所有企鹅移动到同一行的情况,因为棋盘的长宽和企鹅数量相等,且同一个格子只能有一个企鹅,所以这些企鹅应该各自独占一列,为了让步数尽量小,把横坐标排序后,第iii只企鹅应该移动到横坐标为iii的位置,对应的贡献为abs(xi−i)abs(x_i-i)abs(xi−i);接下来考虑把它们移动到同一行的问题,结论是把纵坐标从小到大排原创 2021-03-06 00:55:52 · 204 阅读 · 0 评论 -
力扣 354. 俄罗斯套娃信封问题 LIS sort
https://leetcode-cn.com/problems/russian-doll-envelopes/思路:先按照www从小到大对输入进行排序,那么问题就转换成了LISLISLIS,但是还有一些地方需要注意,套娃时信封的w、hw、hw、h要求都是单调递增的,所以排序后www相等的信封只能选111个,怎么保证这一点呢?在www相等时,我们可以按照hhh从大到小排序,这样在计算LISLISLIS时相同wewewe的信封一定最多选一个。class Solution {public: in原创 2021-03-04 16:36:16 · 179 阅读 · 1 评论 -
PIPIOJ 1466: PIPI捡垃圾Ⅱ 堆 思维
http://pipioj.online/problem.php?id=1466思路:利用堆可快速求出中位数(当然诸如TreapTreapTreap之类的数据结构也是可以的),思路就是用大根堆维护最小的(n+1)/2(n+1)/2(n+1)/2个元素,用小根堆维护最大的n/2n/2n/2个元素,那么中位数要么等于大根堆堆顶要么等于两个堆顶之和再除222。#include<bits/stdc++.h>#define INF 0x3f3f3f3fusing namespace std;原创 2021-03-04 01:00:43 · 194 阅读 · 2 评论 -
PIPIOJ 1463: PIPI的字符串问题IX set
http://www.pipioj.online/problem.php?id=1463思路:把字符串丢到setsetset里面即可,但是直接丢太暴力了。空间复杂度和时间复杂度都很高,我们可以把长度为nnn的仅包含ccc的字符串抽象为一对数据:(c,n)(c,n)(c,n),把这一对数据插入到setsetset中维护即可。#include<bits/stdc++.h>#define INF 0x3f3f3f3fusing namespace std;const int maxn=1原创 2021-03-03 23:01:47 · 164 阅读 · 1 评论 -
力扣 304. 二维区域和检索 - 矩阵不可变 二维前缀和
https://leetcode-cn.com/problems/range-sum-query-2d-immutable/思路:二维前缀和,查询时可以把区域划分为四块,O(nm)O(nm)O(nm)初始化,O(1)O(1)O(1)查询。class NumMatrix {public: vector<vector<int>> sum; NumMatrix(vector<vector<int>>& matrix) {原创 2021-03-02 14:23:10 · 212 阅读 · 0 评论 -
力扣 1178. 猜字谜 位运算 思维
https://leetcode-cn.com/problems/number-of-valid-words-for-each-puzzle/思路:看完题目会发现关键点是一个单词中出现的字符种类,和个数没有关系,那么我们可以用位运算表示某个单词含有的字符种类。具体做法是,如果它含有小写字母xxx,我们就可以把它二进制表示的第x−′a′x-'a'x−′a′位置为111。这样就将字符串变成了整数,接下来构建一个哈希表,记录某个整数所对应的字符串个数。对于每个puzzlepuzzlepuzzle我们可以得到它原创 2021-02-28 14:21:36 · 209 阅读 · 0 评论 -
力扣 1052. 爱生气的书店老板 思维 枚举 滑动窗口
https://leetcode-cn.com/problems/grumpy-bookstore-owner/思路:硬要说的话感觉我这个解法怪怪的,和平时见到的滑动窗口不太一样,因为窗口大小是固定不变的。看完题目,很容易想到使用一个长度固定为XXX的窗口,然后枚举左边界即可,那么怎么保证整体复杂度是O(n)O(n)O(n)的呢?利用前缀和的思想,在初始化时以当前窗口的左右边界(初始时窗口为[0,X)[0,X)[0,X))为限,可以计算出一个前缀和和后缀和,那么在移动窗口的时候维护这两个和值即可。cl原创 2021-02-23 19:45:32 · 163 阅读 · 0 评论 -
力扣 766. 托普利茨矩阵 思维
https://leetcode-cn.com/problems/toeplitz-matrix/思路:直接判断就行,很简单……主要说一下进阶怎么做,第一种情况可以用一个数组记录当前行的元素,在读入下一行矩阵时和它比较即可。第二种情况需要对矩阵进行划分,保证每个子矩阵都满足题意即可,注意也要保证子矩阵和子矩阵之间也是满足题意的,所以两个相邻的矩阵至少要有某一列或某一行是重合的。class Solution {public: bool isToeplitzMatrix(vector<v原创 2021-02-22 18:19:38 · 177 阅读 · 0 评论 -
力扣 1004. 最大连续1的个数 III 滑动窗口
https://leetcode-cn.com/problems/max-consecutive-ones-iii/思路:滑动窗口模板题吧……由于求的是最长连续子数组的长度,那么在维护窗口时没必要将其缩小(因为我们要的是最优解),这样就不需要额外操作来记录最大值了。class Solution {public: int longestOnes(vector<int>& A, int K) { int l=0,r=0,n=A.size();原创 2021-02-19 14:29:08 · 220 阅读 · 0 评论 -
力扣 995. K 连续位的最小翻转次数 模拟 差分 思维
https://leetcode-cn.com/problems/minimum-number-of-k-consecutive-bit-flips/思路:想法很简单,从前往后遍历,如果某个位置不是111,就从这个位置开始向后翻转。但是如果暴力写的话,复杂度可能会达到O(nk)O(nk)O(nk),喜提一发TLETLETLE,比如下面这份代码:class Solution {public: int minKBitFlips(vector<int>& A, int K) {原创 2021-02-18 16:31:53 · 341 阅读 · 0 评论