
LeetCode
chr1st0pher
Dancer on the keyboard
展开
-
Leetcode 46. 全排列
Description求给定排列的全排列Codeclass Solution {public: vector<vector<int>> permute(vector<int>& nums) { vector<vector<int>>res; sort(nums.begin(), nums.end()); do{ res.push_back(nums);原创 2021-03-04 20:42:52 · 202 阅读 · 1 评论 -
Leetcode 1438. 绝对差不超过限制的最长连续子数组(双指针+单调队列)
Description给你一个整数数组 nums ,和一个表示限制的整数 limit,请你返回最长连续子数组的长度,该子数组中的任意两个元素之间的绝对差必须小于或者等于 limit 。如果不存在满足条件的子数组,则返回 0 。Solution首先发现显然可以用双指针来计算答案,重点在于如何维护当前段内的最大最小值动态维护当前窗口内的最大值和最小值,可以采用单调队列时间复杂度O(N)O(N)O(N)空间复杂度O(N)O(N)O(N)Codeclass Solution {public:原创 2021-03-04 15:20:56 · 277 阅读 · 1 评论 -
剑指 Offer 59 - II. 队列的最大值(单调队列)
Description请定义一个队列并实现函数 max_value 得到队列里的最大值,要求函数max_value、push_back 和 pop_front 的均摊时间复杂度都是O(1)。若队列为空,pop_front 和 max_value 需要返回 -1Solution思路与剑指 Offer 30. 包含min函数的栈 类似,本质上也是相似的空间换时间的套路。维护两个队列,一个是正常队列,一个是非降的单调(双向)队列,若当前要压入队列的元素x比单调队列尾的元素y 大,则弹出队尾元素,并继续判原创 2021-03-01 23:53:46 · 128 阅读 · 0 评论 -
剑指 Offer 51. 数组中的逆序对(BIT + 离散化)
Description在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。Solution比较裸的求逆序对,这里采用的是竞赛中常用的BIT求法时间复杂度:O(NlogN)O(N\log N)O(NlogN)空间复杂度:O(N)O(N)O(N)Codeclass Solution {public: static const int maxn = 5e4 + 7; int lim,bit[maxn];原创 2021-03-01 21:45:47 · 159 阅读 · 0 评论 -
剑指 Offer 49. 丑数(小根堆)
Description我们把只包含质因子 2、3 和 5 的数称作丑数(Ugly Number)。求按从小到大的顺序的第 n 个丑数。111是丑数nnn 不超过169016901690Solution因为要求从小到大的第n个丑数,所以我们采用小根堆,每次弹出当前最小的丑数,并把它的2/3/5倍插入小根堆即可注意还需要判重(set)Codeclass Solution {public: typedef long long ll; set<ll>s; c原创 2021-03-01 21:23:39 · 120 阅读 · 0 评论 -
剑指 Offer 52. 两个链表的第一个公共节点(LCA)
Description输入两个链表,找出它们的第一个公共节点。若不存在则返回NULL要求时间复杂度O(N), 空间复杂度O(1)Solution有点类似寻找LCA,故可借用朴素求LCA的思想,先把两个节点拉到同一深度,再同时向树根跳,第一次相遇的节点就是LCA。因此,本质上我们只需要预先求出两个链表长度的差值,再按照求LCA的方法即可。Code/** * Definition for singly-linked list. * struct ListNode { * int va原创 2021-02-24 01:07:31 · 110 阅读 · 0 评论 -
剑指 Offer 31. 栈的压入、弹出序列(思维)
DescriptionSolution若当前弹出的为x,那压栈队列中x之前的元素肯定已经被压过栈了基于这一点,容易发现:对于当前弹出序列的某一元素x, 若x比之前的弹出序列中在压栈序列中下标最大的元素下标还要大,那此次弹出合法若小于,且当前栈顶元素不等于x,则不合法,反之则合法我们只需要维护当前弹出序列元素在压栈序列中下标最大的元素的下标,并同时维护一个栈即可。时间复杂度:O(N)空间复杂度:O(N)Codeclass Solution {public: static con原创 2021-02-24 00:05:50 · 103 阅读 · 0 评论 -
剑指 Offer 30. 包含min函数的栈(单调栈)
Description定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的 min 函数在该栈中,调用 min、push 及 pop 的时间复杂度都是 O(1)。Solution光靠一个栈必然是无法实现O(1)查询min的,故我们考虑再加一个栈在维护一个正常的栈sta1的同时,维护一个非减的栈sta2(top是最小值之一)每次查询min的值时即为栈sta2顶的值为什么这样是正确的?假设当前需要push的值为x, 而sta2栈顶的值为y:若x > y,按照我们的设计,x不需要压入原创 2021-02-19 22:28:35 · 106 阅读 · 0 评论 -
剑指 Offer 28. 对称的二叉树(二叉树的镜像)
DescriptionSolution二叉树和它的镜像,实际上就是在层序遍历中每一层是左儿子优先还是右儿子优先的区别实现上,我们这两种遍历方法同时进行,若每次遍历到的节点都相同,则证明一颗二叉树是对称的时间复杂度:O(N)O(N)O(N)空间复杂度:O(N)O(N)O(N)Code/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; *原创 2021-02-19 21:17:30 · 96 阅读 · 0 评论 -
Leetcode 1004. 最大连续1的个数 III (双指针)
DescriptionSolution显然满足双指针中的单调性,即左指针+1的情况下,右指针(非严格)递增Codeclass Solution {public: int longestOnes(vector<int>& A, int K) { int l = 0, r = 0, res = 0; int cnt = K, n = A.size(); if(!K) { int tmp = 0;原创 2021-02-19 21:11:09 · 118 阅读 · 0 评论 -
Leetcode 995. K 连续位的最小翻转次数(贪心 + 双向队列)
DescriptionSolution观察发现,当从头开始处理到第 iii 位(前面的位数都为111)时, 若该位(在考虑被之前的翻转所影响的情况下)为 000,则必须翻转,且是以从第 iii 位开始向后K个长度的翻转(因为前面的位数都为111了,再翻转它们没有任何意义),所以我们可以贪心的进行翻转操作,即可满足最少次数的要求。实现上,采用双端队列的方式,动态维护能影响到当前位的所有翻转,根据现存翻转个数来判断该位的当前值(奇数个则取反,偶数个不变)时间复杂度 O(N)O(N)O(N)空间复杂度原创 2021-02-18 23:35:14 · 192 阅读 · 0 评论 -
剑指 Offer 41. 数据流中的中位数(大根堆+小根堆)
DescriptionSolution经典问题,用一个大根堆和一个小根堆来维护数据流的中位数,稍微手推一下即可Hint priority_queue<int,vector<int>,greater<int> >q2;//小根堆 priority_queue<int,vector<int>,less<int> >q1;//大根堆Codeclass MedianFinder {public: /**原创 2021-02-11 00:45:54 · 203 阅读 · 1 评论 -
剑指 Offer 35. 复杂链表的复制(Map)
DescriptionSolution存在两种拷贝:深拷贝和浅拷贝深拷贝主要是将另一个对象的属性值拷贝过来之后,另一个对象的属性值并不受到影响,因为此时它自己在堆中开辟了自己的内存区域,不受外界干扰。浅拷贝主要拷贝的是对象的引用值,当改变对象的值,另一个对象的值也会发生变化。而本题需要我们用深拷贝来复制该复杂链表,若每个节点只有一个next指针指向下一个节点,则只需要顺序遍历一遍待拷贝链表,同时复制一份即可;但这里还有一个random指针,所有我们需要同时建立原链表和新链表内存地址的对原创 2021-02-10 22:41:36 · 133 阅读 · 0 评论 -
Leetcode 1423. 可获得的最大点数(前缀和)
DescriptionSolution最终的方案一定是前缀+后缀,故 O(N)O(N)O(N)前缀和枚举即可Codeclass Solution {public: int maxScore(vector<int>& cardPoints, int k) { int sz = cardPoints.size(); vector<int>sum(sz); for(int i = 0;i < sz;++i)原创 2021-02-10 22:19:38 · 169 阅读 · 0 评论 -
Leetcode 567. 字符串的排列(双指针)
DescriptionSolution双指针 + check(), 复杂度O(32∗N)O(32*N)O(32∗N)Codeclass Solution {public: inline bool check(int *sum) { for(int i = 0;i < 26;++i) { if(sum[i] != 0) return false; }return true; } bool checkInclus原创 2021-02-10 22:15:46 · 130 阅读 · 0 评论 -
剑指 Offer 64. 求1+2+…+n (二进制)
DescriptionSolution第一眼觉得有点离谱,啥都不让用;突然想到一种只用加减和移位运算符来模拟乘法的方法,核心思想类似快速乘(龟速乘),将乘数进行二进制差分,对被除数进行移位后再相加。Codeclass Solution {public: typedef long long ll; ll mul(ll a,ll b) { ll res = 0, cnt = 0; res += ((a << cnt) & ((b&a原创 2021-02-05 23:08:47 · 115 阅读 · 0 评论 -
Leetcode 424. 替换后的最长重复字符 (双指针)
DescriptionSolution双指针Codeclass Solution {public: inline int MAX(int a,int b) {return a > b ? a : b;} int get_mx(int *sum) { int mx = 0; for(int i = 0;i < 26;++i) mx = MAX(mx, sum[i]); return mx; } int ch原创 2021-02-03 00:09:20 · 119 阅读 · 0 评论 -
Leetcode 1579. 保证图可完全遍历(思维 + 生成树)
DescriptionSolution首先注意到本题中的“完全遍历”概念本质上就是某人能走的边集为原图的一颗生成树故我们可以借鉴生成树算法的思想:避圈法(也就是kruskal的核心思想)再做思考,可删除的边分为两类,一类是某人独有的边,一类是二人共有的若我们删除某人独有的边,在不影响它本身的“完全遍历”性质的前提下,对另一个人的该性质无影响所以我们若要删除尽可能多的边,就应该优先删除独有边,再删除共有边本题一个不可忽视的条件所有元组 (typei, ui, vi) 互不相同该条件说明原创 2021-01-27 02:37:00 · 220 阅读 · 0 评论 -
Leetcode 25. K 个一组翻转链表 (模拟)
DescriptionSolution题目要求: 常数额外空间 && 实际上的节点交换先遍历一遍链表获取链表长度,再通过一次遍历进行节点交换第二次遍历时, 将链表按 k 个一组分组, 记录下每组的第一个和最后一个本质上就是把组内节点倒过来, 把前一组的第一个节点指向该组最后一个节点即可具体实现细节见代码时间复杂度:O(N)O(N)O(N)空间复杂度:O(1)O(1)O(1)Code/** * Definition for singly-linked list. *原创 2021-01-25 21:26:29 · 111 阅读 · 0 评论 -
Leetcode 1691. 堆叠长方体的最大高度(拓扑排序 + DP)
DescriptionSolution一个立方体可以任意翻转, 我们可以当成多个不同的立方体看待。问题转化为:有最多N*6个立方体, 最高能垒多高考虑DP[i], 第i个立方体放在最上面时的最大高度, 发现当前的状态是由所有可以垒在其下面的立方体转移过来的,所以我们考虑一边拓扑排序一边DPCodeclass Solution {public: #define N 202 struct cube{ int a,b,c; }; vector<原创 2020-12-24 23:44:34 · 320 阅读 · 0 评论 -
Leetcode 周赛#220 D. 检查边长度限制的路径是否存在 (并查集+离线)
DescriptionSolution将询问和边集按照边权从小到大排序后, 每次将比当前询问的lim小的边加入并查集中, 再判断此时两点是否连通即可Codeclass Solution {public: #define maxn 100005 int fa[maxn]; int find(int x) {return x == fa[x] ? x : fa[x] = find(fa[x]);} struct node{ int u,v,lim;原创 2020-12-24 10:34:50 · 121 阅读 · 0 评论 -
Leetcode 135. 分发糖果 (拓扑排序)
DescriptionSolution以孩子间的关系建单向边,每个点在拓扑排序中的层数之和即为答案Hint评分相同的孩子需要建双向边Codeclass Solution {public: #define maxn 200005 int d[maxn]; vector<int>edge[maxn]; inline void add(int u,int v) { edge[u].push_back(v); d[v]++;原创 2020-12-24 10:29:28 · 155 阅读 · 1 评论 -
Leetcode 842. 将数组拆分成斐波那契序列(模拟)
DescriptionSolution当类Fibonacci数列的前两项确定时,整个序列便确定了, 故我们只需要枚举前两项,在check一下是否合法即可小模拟Codeclass Solution {public: #define inf 0x3f3f3f3f int toint(string s) { if(s.size() > 10) return -1; long long res = 0; for(int i = 0;原创 2020-12-09 15:18:39 · 93 阅读 · 0 评论 -
Leetcode 621. 任务调度器(贪心)
DescriptionSolution先统计一下不同种类的任务出现次数, 在任意时刻,当前剩余次数最多的任务的优先级最高故可贪心的选取当前剩余个数最多的任务(“长作业优先" )Codeclass Solution {public: int leastInterval(vector<char>& tasks, int n) { int num[26];memset(num,0,sizeof(num)); int sz = tasks.s原创 2020-12-05 21:33:49 · 245 阅读 · 0 评论 -
Leetcode 659. 分割数组为连续子序列(贪心)
DescriptionSolution分割出来的子序列需要尽可能的长,所以我们对于每个数,都贪心的放入目前放入的最短的子序列即可采用离散化+优先队列实现时间复杂度O(N∗logN)O(N* \log N)O(N∗logN)Codeclass Solution {public: int mp[3*10007]; priority_queue<int,vector<int>,greater<int> >q[3*10007]; bool原创 2020-12-05 10:30:25 · 178 阅读 · 0 评论 -
LeetCode 767. 重构字符串(思维+构造)
题目链接DescriptionSolution先将S串中出现的不同字母计数,设出现次数最多的字母出现了x次容易发现当x - 1 > S.size() - x 时,不存在答案;其他情况下答案一定存在考虑特殊构造:我们开辟一个列数为x的矩阵,按照字母出现次数顺序依次一行行填入因为是按照字母出现次数从大到小的顺序填字母,所以必然不可能存在同一种字母在列中相邻(1)最后按照列从小到大的顺序依次将每列的字母按照行从小到大的顺序放入答案中因为(1)的性质存在,所以答案字符串中一定不存在相邻两个字原创 2020-11-30 20:39:44 · 173 阅读 · 0 评论 -
LeetCode 452. 用最少数量的箭引爆气球(贪心)
题目链接Solution按右端点排序后贪心的取右端点Codeclass Solution {public: bool vis[10010]; struct node{ int l,r; inline bool operator < (const node&it) const{ return r < it.r; } }num[10010]; int findMinArrowSh原创 2020-11-24 22:39:51 · 99 阅读 · 0 评论 -
LeetCode 685. 冗余连接 II (并查集 + 树上乱搞)
题目链接Solution输入的边有N条,其中有一条为“附加边”,但我们不知道是哪条边。但这条边的存在会使得原本的有根树出现严格一个环(不考虑方向)。我们一边加边,一边将两端点用并查集合并,当两端点在合并前就属于同一个并查集时,说明加上这条边后就会出现环于是就找到了原图中唯一的环,我们用dfs将环上的点标记最后倒序枚举输入的边,若当前边在环上,且删去后图中入度为0的点有且只有一个,那么就找到了答案Codeclass Solution {public: int N, fa[1000原创 2020-09-17 21:16:10 · 127 阅读 · 0 评论 -
LeetCode 1248. 统计「优美子数组」(暴力)
Description题目链接Solution存下奇数数字的下标,暴力即可Codeclass Solution {public: vector<int>id; int numberOfSubarrays(vector<int>& nums, int k) { int n = nums.size(); for(int i = 0;i < n;++i) { if(nums[i]&1)原创 2020-11-19 14:44:24 · 93 阅读 · 0 评论