牛客、leetcode题解
文章平均质量分 58
powerof10
Be Brilliant
展开
-
快速排序/堆排序/归并排序总结(C++版)
1. 快速排序平均/最好时间复杂度O(nlogn),最坏时间复杂度O(n^2),不稳定工作过程:区间内只剩一个/没有数时,结束递归找区间左端当作参考值 ref 进行划分 partition ,并得到 ref 应该在的index;划分后 index 左边的都比 ref 小,右边的都比 ref 大对 index 左右递归的进行快速排序快排代码:#include<iostream>#include<vector>using namespace std;void原创 2021-03-19 10:54:57 · 383 阅读 · 0 评论 -
双端单调队列解决队列最大值、滑动窗口最大值问题
题目1:队列中的最大值分析:此题求队列中的最大值,队列的特点是先进先出,因此在一个数字入队时,比它先进且比它小的数字不会对答案产生影响。举个例子,比如当前队列是1、2、3、4,下一个入队的是6,按照出队顺序,如果1、2、3、4还在队列中,那么比它晚入队的6必然也在队列中,取最大值轮不上1、2、3、4。基于这个特点,可以在每次入队前舍弃掉队列中比该数小的数,使得队列中仅保留对结果有影响的数字。等价于维护一个辅助的单调递减队列,入队时要从尾部弹出比当前数小的,因此必须是双端队列。①入队过程:队原创 2021-01-18 21:38:08 · 216 阅读 · 0 评论 -
判断一个字符串是否表示数值
题目链接,描述如下:解题思路:把一个数字分为三个部分,num1 . num2 e/E num3其中,num1和num3是可以有符号的,num2是无符号整数;①首先扫描第一部分,判断其是否是整数②如果遇到 在这里插入代码片...原创 2021-01-18 16:03:03 · 391 阅读 · 0 评论 -
单词规律-split + 找第一次出现的下标,无需哈希表
题目链接如下:Leetcode 290-单词规律思路:①首先对str进行split,得到包含所有token的vector,名为res②对于pattern字符串,用string的find方法找到每一个字符出现的第一个位置比如:egg 对应的是 011str 对应的是 012wwo 对应的是 001③对于token的vector,用algorithm库中的find方法找到每个token出现的第一个位置(迭代器),减去res.begin(),即第一次出现的下标。比如:dog cat ca原创 2020-12-16 10:54:55 · 284 阅读 · 0 评论 -
符合目标和的二叉树路径及扩展问题-leetcode 113、437
题目链接如下:路径总和 II路径综合 III先看第一个,题目描述如下:这道题路径是从根节点开始,到叶子结点结束,因此要递归到叶子结点才判断路径和是否符合。用数组tmp存每个符合目标的路径,二维的res存最终结果。分情况讨论:①空节点直接返回 if(!root) return;不是空节点:更新curSum、当前路径容器tmp tmp.push_back(root->val); curSum+=root->v原创 2020-12-15 14:54:30 · 122 阅读 · 0 评论 -
逆序/翻转对与归并排序-剑指offer 51、leetcode 493
题目链接如下:Leetcode 493-翻转对剑指Offer 51-数组中的逆序对两个题目类似,以493题为例:暴力解法即进行两层遍历,时间复杂度为O(n^2),这显然不符合要求。为了实现更低的时间复杂度,使用递归的归并排序。思路:①求出中间位置mid,对 [left, mid] 、[mid+1, right] 两个区间分别做归并排序,并返回左右两个区间的逆序对数。②所求 = 左区间逆序对数 + 右区间逆序对数 + 左右之间的逆序对数。③对两个区间进行合并,并返回上一层递归。递归结束的条原创 2020-12-15 10:36:10 · 171 阅读 · 0 评论 -
验证 IPv4 / IPv6 地址(C++) -Leetcode 468
这道题本来很早就刷了,还把C++的split实现单独写了一篇,由于拖延症晚期一直没总结,下面进入正题首先题目链接如下Leetcode 468-验证IP地址牛客 NC113-验证IP地址题目要求如下:思路:(1)首先IPv4和IPv6的判断要分为两个不同的函数,根据传入string中.、:的数量决定传入哪个函数,还是直接返回"Neither"(还好C++的algorithm库中自带count,要不什么都要自己造轮子实在有点难受hh)代码如下: vector<string> res原创 2020-12-10 18:04:32 · 2162 阅读 · 0 评论 -
TopK问题-优先队列和基于partition减治、自己实现堆调整3种方法
牛客NC88-寻找第K大Leetcode 215-数组中第K个最大元素思路1:求第k大,维护一个小根堆,用优先队列priority_queue过程:向小根堆中插入k个数,遍历剩下的n-k个数,当前数比堆顶大时,交换他们的值。这样遍历完,堆顶是小根堆k个数中最小的,且比剩余的n-k的数都大,因此堆顶即为所求;此外,小根堆中所有的数是整个数组的前K大。代码如下(Leetcode 215):class Solution {public: int findKthLargest(vector&原创 2020-11-16 10:51:59 · 356 阅读 · 0 评论 -
用C++实现split分割字符串
前几天做到一个牛客NC113-验证IP地址的题目,用python和Java都可以轻松的调用库函数来实现字符串的分割,分别验证每一个token是否合法。奈何C++标准库中没有这个函数,那就自己来实现一下。首先,回忆一下C++带有空格的输入流的读取,用getline来实现,getline默认遇到回车\n而非空格而结束读取。①getline用法如下(引自cplusplus.com)(1) istream& getline (istream& is, string& str, char原创 2020-11-04 22:23:31 · 852 阅读 · 0 评论 -
用unordered_map和双向链表实现LRU缓存
LRU为最近最少使用算法,可以类比为手机app多任务管理来理解,每个app刚用完在会被放在最前面,当内存满时,最久没用的app内存会被释放,题目链接如下:Leetcode 146-LRU缓存机制题目要求:put和get操作时间复杂度为O(1)分析:首先,这些key-value的数据应该按时间顺序排列,链表是有序的;但链表查询时间为O(n),无法满足要求;哈希表查询时间为O(1),但是无序的。因此可以用哈希表来存储key和链表节点指针的映射;每次最新访问或存储的数据放在链表的头部,当cac原创 2020-11-04 21:13:32 · 345 阅读 · 0 评论 -
关于搜索二叉树与中序遍历
一般搜索二叉树的题都可以用中序遍历做,今天又做了一道题,发现有一些小细节需要注意,总结一下。(1)首先是一道很直接的题,判断一颗树是否为二叉搜索树。如①牛客NC60-判断一颗树是否为搜索二叉树及完全二叉树②Leetcode 98-验证二叉搜索树有一种比较常见的错误思路:用递归的思想,首先判断当前的节点是否满足大于左孩子 && 小于右孩子;若符合,再递归判断它的左右子树是否均为二叉搜索树,写成代码如下:bool isSerch(TreeNode* root){ if(!r原创 2020-10-31 21:02:41 · 1506 阅读 · 1 评论 -
priority_queue、自己实现堆调整两种方式,求数据流中的中位数
题目描述如下:要求插入的时间复杂度是O(logN),取中位数的时间复杂度是O(1)想到用优先队列priority_queue,插入时可以动态实现堆的调整思路:用大根堆存 <=中位数的那部分数,smallPart,存n/2个用小根堆存 >= 中位数的那部分数,bigPart,存n/2或n/2+1个 priority_queue<double> smallPart;//大根堆存储小的那部分 priority_queue<double,vector<doub原创 2020-10-23 15:14:56 · 409 阅读 · 0 评论 -
数组作为哈希表-leetcode 763、leetcode 1002
今天的每日一题Leetcode 763-划分字母区间用到了用数组存储的哈希表,index为小写字母的序号(ch-‘a’),value为最后出现的位置题目描述思路:初始化区间下界start、end均为0。遍历整个字符串,根据每个字母出现的位置更新上界end,因为要保证只有当前区间有这个字符,所以上界end要取max(end, last[S[i]-'a'])代码如下:class Solution {public: vector<int> partitionLabels(stri原创 2020-10-22 10:15:31 · 204 阅读 · 0 评论 -
中缀表达式转为逆波兰式并求值(牛客NC137-表达式求值-C++实现)
今天刷牛客遇到一个表达式求值的题,题目链接如下:牛客NC137-表达式求值这道题与Leetcode 224-基本计算器类似,但Leetcode这道题没有要求乘法涉及到编译原理的内容,后缀表达式计算起来比较容易,复习了一下将中缀表达式转化为后缀表达式的方法。①要用到两个stack:一个放数字、一个放运算符,由于数字可能有多位,且存在运算符栈顶pop后向数字栈push的情况,因此两个stack数据类型定义为string。②由于放数字的栈存放最后后缀表达式,且需要一次弹出逆序,果断一开始就用queue来原创 2020-10-21 22:33:03 · 831 阅读 · 0 评论