牛客网高频面试算法题
面试算法刷题笔记
沉浮一湘蕉
心若沉浮,浅笑安然。
展开
-
BM100 设计LRU缓存结构
3. set(key, value):将记录(key, value)插入该结构,如果关键字 key 已经存在,则变更其数据值 value,如果不存在,则向缓存中插入该组 key-value ,如果key-value的数量超过capacity,弹出最久未使用的key-value。3.返回的value都以字符串形式表达,如果是set,则会输出"null"来表示(不需要用户返回,系统会自动输出),方便观察。1.某个key的set或get操作一旦发生,则认为这个key的记录成了最常使用的,然后都会刷新缓存。...原创 2022-08-12 13:38:10 · 229 阅读 · 0 评论 -
BM97 旋转数组
描述一个数组A中存有 n个整数,在不允许使用另外数组的前提下,将每个整数循环向右移 M( M >=0)个位置,即将A中的数据由(A0A1……AN-1)变换为(AN-M…… AN-1A0A1……AN-M-1)(最后 M 个数循环移至最前面的 M 个位置)。如果需要考虑程序移动数据的次数尽量少,要如何设计移动的方法?class Solution {public: /** * 旋转数组 * @param n int整型 数组长度 * @param m int整型 右移距...原创 2022-04-08 21:27:39 · 389 阅读 · 0 评论 -
BM96 主持人调度(二)
描述有 n个活动即将举办,每个活动都有开始时间与活动的结束时间,第 i个活动的开始时间是 starti,第 i个活动的结束时间是 endi,举办某个活动就需要为该活动准备一个活动主持人。一位活动主持人在同一时间只能参与一个活动。并且活动主持人需要全程参与活动,换句话说,一个主持人参与了第 i个活动,那么该主持人在 (starti,endi)这个时间段不能参与其他任何活动。求为了成功举办这 n个活动,最少需要多少名主持人。思路:首先:要对活动进行排序:开始时间相等的,结束时间从小...原创 2022-04-17 20:38:20 · 334 阅读 · 0 评论 -
BM95 分糖果问题
描述一群孩子做游戏,现在请你根据游戏得分来发糖果,要求如下:1. 每个孩子不管得分多少,起码分到一个糖果。2. 任意两个相邻的孩子之间,得分较多的孩子必须拿多一些糖果。(若相同则无此限制)给定一个数组arrarr代表得分数组,请返回最少需要多少糖果。思路:1.把所有孩子的糖果数初始化为 1;2.先从左往右遍历一遍,如果右边孩子的评分比左边的高,则右边孩子的糖果数更新为左边孩子的 糖果数加 1;3.再从右往左遍历一遍,如果左边孩子的评分比右边的高,且左边孩子当前的糖果数不大..原创 2022-04-16 21:47:15 · 226 阅读 · 0 评论 -
BM93 盛水最多的容器
描述给定一个数组height,长度为n,每个数代表坐标轴中的一个点的高度,height[i]是在第i点的高度,请问,从中选2个高度与x轴组成的容器最多能容纳多少水class Solution {public: /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param height int整型vector * @return int整型 */ int maxArea(vector<int>& height)原创 2022-04-08 21:01:03 · 209 阅读 · 0 评论 -
BM85 验证IP地址
描述编写一个函数来验证输入的字符串是否是有效的 IPv4 或 IPv6 地址IPv4 地址由十进制数和点来表示,每个地址包含4个十进制数,其范围为 0 - 255, 用(".")分割。比如,172.16.254.1;同时,IPv4 地址内的数不会以 0 开头。比如,地址 172.16.254.01 是不合法的。IPv6 地址由8组16进制的数字来表示,每组表示 16 比特。这些组数字通过 (":")分割。比如, 2001:0db8:85a3:0000:0000:8a2e:0370:7334 是一.原创 2022-04-16 21:17:31 · 98 阅读 · 0 评论 -
BM82 买卖股票的最好时机(三)
描述假设你有一个数组prices,长度为n,其中prices[i]是某只股票在第i天的价格,请根据这个价格数组,返回买卖股票能获得的最大收益1. 你最多可以对该股票有两笔交易操作,一笔交易代表着一次买入与一次卖出,但是再次购买前必须卖出之前的股票2. 如果不能获取收益,请返回03. 假设买入卖出均无手续费class Solution {public: /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * 两次交易所能获得的最大原创 2022-04-16 18:34:48 · 121 阅读 · 0 评论 -
BM79 打家劫舍(二)
描述你是一个经验丰富的小偷,准备偷沿湖的一排房间,每个房间都存有一定的现金,为了防止被发现,你不能偷相邻的两家,即,如果偷了第一家,就不能再偷第二家,如果偷了第二家,那么就不能偷第一家和第三家。沿湖的房间组成一个闭合的圆形,即第一个房间和最后一个房间视为相邻。给定一个长度为n的整数数组nums,数组中的元素表示每个房间存有的现金数额,请你计算在不被发现的前提下最多的偷窃金额。思路:如果只有一间房屋,则偷窃该房屋,可以偷窃到最高总金额。如果只有两间房屋,则由于两间房屋相邻,不能同时偷窃,只能原创 2022-04-16 14:57:26 · 167 阅读 · 0 评论 -
BM78 打家劫舍(一)
描述你是一个经验丰富的小偷,准备偷沿街的一排房间,每个房间都存有一定的现金,为了防止被发现,你不能偷相邻的两家,即,如果偷了第一家,就不能再偷第二家;如果偷了第二家,那么就不能偷第一家和第三家。给定一个整数数组nums,数组中的元素表示每个房间存有的现金数额,请你计算在不被发现的前提下最多的偷窃金额。思路:或许有人认为利用贪心思想,偷取最多人家的钱就可以了,要么偶数家要么奇数家全部的钱,但是有时候会为了偷取更多的钱,或许可能会连续放弃两家不偷,因此这种方案行不通,我们依旧考虑动态规划。原创 2022-04-16 14:24:57 · 400 阅读 · 0 评论 -
BM71 最长上升子序列(一)
描述给定一个长度为 n 的数组 arr,求它的最长严格上升子序列的长度。所谓子序列,指一个数组删掉一些数(也可以不删)之后,形成的新数组。我们定义一个序列是 严格上升 的,当且仅当该序列不存在两个下标 i 和 j 满足 i<j 且arri≥arrj。输入:[6,3,1,5,2,3,7]返回值:4说明:该数组最长上升子序列为 [1,2,3,7] ,长度为4class Solution {public: /** * 代码中的类名、方法名、参数名已经指定,请原创 2022-04-16 18:56:42 · 78 阅读 · 0 评论 -
BM69 把数字翻译成字符串
描述有一种将字母编码成数字的方式:'a'->1, 'b->2', ... , 'z->26'。我们把一个字符串编码成一串数字,再考虑逆向编译成字符串。由于没有分隔符,数字编码成字母可能有多种编译结果,例如 11 既可以看做是两个 'a' 也可以看做是一个 'k' 。但 10 只可能是 'j' ,因为 0 不能编译成任何结果。现在给一串数字,返回有多少种可能的译码结果状态方程:f(i)=f(i−1)+f(i−2)边界条件是 f(-1) = 0,f(0) = 1。优化原创 2022-04-17 19:52:48 · 280 阅读 · 0 评论 -
BM64 最小花费爬楼梯
描述给定一个整数数组cost ,其中 cost[i]是从楼梯第i 个台阶向上爬需要支付的费用,下标从0开始。一旦你支付此费用,即可选择向上爬一个或者两个台阶。你可以选择从下标为 0 或下标为 1 的台阶开始爬楼梯。请你计算并返回达到楼梯顶部的最低花费。class Solution {public: /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param cost int整型vector * @return int整...原创 2022-04-08 21:15:49 · 375 阅读 · 0 评论 -
BM61 矩阵最长递增路径
描述给定一个 n 行 m列矩阵 matrix,矩阵内所有数均为非负整数。 你需要在矩阵中找到一条最长路径,使这条路径上的元素是递增的。并输出这条最长路径的长度。这个路径必须满足以下条件:1. 对于每个单元格,你可以往上,下,左,右四个方向移动。 你不能在对角线方向上移动或移动到边界外。2. 你不能走重复的单元格。即每个格子最多只能走一次。思路:在图论中,拓扑排序(Topological Sorting)是一个有向无环图(DAG, Directed Acyclic Graph)的所..原创 2022-04-16 20:42:53 · 231 阅读 · 0 评论 -
BM55 没有重复项数字的全排列
描述给出一组数字,返回该组数字的所有排列class Solution { vector<int> vis;public: void backtrack(vector<vector<int> >& res, vector<int>& ans, vector<int>& nums, int idx) { if (idx == nums.size()) { res.emplace_back(ans)原创 2022-04-15 17:21:34 · 404 阅读 · 0 评论 -
BM52 数组中只出现一次的两个数字
描述一个整型数组里除了两个数字只出现一次,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。思路:1.所有的数异或后的结果,其中1的那一位表示两个数字中不同的那一位。(两个数字异或,相同位为0,不同位为1)2.根据1所在位置,将所有数字分组,两个数字就被分成两组3.两组数字分别异或得到的结果就是最后的结果class Solution {public: /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param原创 2022-04-14 14:41:44 · 386 阅读 · 0 评论 -
BM48 数据流中的中位数
描述如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。我们使用Insert()方法读取数据流,使用GetMedian()方法获取当前读取数据的中位数。思路:建立一个 大根堆 A 和 小根堆 B ,各保存列表的一半元素。 当两堆的数据个数相等时候,左边堆添加元素。 采用的方法不是直接将数据插入左边堆,而是将数据先插入右边堆,算法调整后,将堆顶的数据插...原创 2022-04-17 19:07:45 · 58 阅读 · 0 评论 -
BM39 序列化二叉树
描述请实现两个函数,分别用来序列化和反序列化二叉树,不对序列化之后的字符串进行约束,但要求能够根据序列化之后的字符串重新构造出一棵与原二叉树相同的树。二叉树的序列化(Serialize)是指:把一棵二叉树按照某种遍历方式的结果以某种格式保存为字符串,从而使得内存中建立起来的二叉树可以持久保存。序列化可以基于先序、中序、后序、层序的二叉树等遍历方式来进行修改,序列化的结果是一个字符串,序列化时通过 某种符号表示空节点(#)二叉树的反序列化(Deserialize)是指:根据某种遍历顺序得到的序列化字原创 2022-04-09 20:20:07 · 996 阅读 · 0 评论 -
BM37 二叉搜索树的最近公共祖先
描述给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。1.对于该题的最近的公共祖先定义:对于有根树T的两个节点p、q,最近公共祖先LCA(T,p,q)表示一个节点x,满足x是p和q的祖先且x的深度尽可能大。在这里,一个节点也可以是它自己的祖先.2.二叉搜索树是若它的左子树不空,则左子树上所有节点的值均小于它的根节点的值; 若它的右子树不空,则右子树上所有节点的值均大于它的根节点的值3.所有节点的值都是唯一的。4.p、q 为不同节点且均存在于给定的二叉搜索树中。/** *原创 2022-04-09 14:43:49 · 93 阅读 · 0 评论 -
BM35 判断是不是完全二叉树
描述给定一个二叉树,确定他是否是一个完全二叉树。完全二叉树的定义:若二叉树的深度为 h,除第 h 层外,其它各层的结点数都达到最大个数,第 h 层所有的叶子结点都连续集中在最左边,这就是完全二叉树。(第 h 层可能包含 [1~2h] 个节点)思路:将每层的节点以层序遍历的方式全部放入队列中(包括null) 如果是完全二叉树,在我们取出节点的时候,应该是直到整棵树遍历完毕才会遇到null。 所以当我们按层序遍历的方式,遇到null,但是队列中仍然存在节点,则代表不是完全二叉树;否则,是完全二原创 2022-04-09 14:20:23 · 585 阅读 · 0 评论 -
BM34 判断是不是二叉搜索树
描述给定一个二叉树根节点,请你判断这棵树是不是二叉搜索树。二叉搜索树满足每个节点的左子树上的所有节点均小于当前节点且右子树上的所有节点均大于当前节点。注意必须中序遍历,这里还要有最大最小范围参数。/** * struct TreeNode { * int val; * struct TreeNode *left; * struct TreeNode *right; * TreeNode(int x) : val(x), left(nullptr), right(nullptr原创 2022-04-08 22:08:05 · 58 阅读 · 0 评论 -
BM32 合并二叉树
描述已知两颗二叉树,将它们合并成一颗二叉树。合并规则是:都存在的结点,就将结点值加起来,否则空的位置就由另一个树的结点来代替。struct TreeNode { int val; struct TreeNode *left; struct TreeNode *right;};class Solution {public: /** * * @param t1 TreeNode类 * @param t2 TreeNode类 * @return TreeNode类 */ T原创 2022-04-08 21:41:23 · 706 阅读 · 0 评论 -
BM30 二叉搜索树与双向链表
描述输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。思路:中序遍历struct TreeNode { int val; struct TreeNode *left; struct TreeNode *right; TreeNode(int x) :val(x), left(nullptr), right(nullptr) {}};class Solution {public: TreeNode* curNode = nullptr; TreeNode* pHea原创 2022-04-08 20:24:11 · 313 阅读 · 0 评论 -
BM22 比较版本号
描述牛客项目发布项目版本时会有版本号,比如1.02.11,2.14.4等等现在给你2个版本号version1和version2,请你比较他们的大小版本号是由修订号组成,修订号与修订号之间由一个"."连接。1个修订号可能有多位数字组成,修订号可能包含前导0,且是合法的。例如,1.02.11,0.1,0.2都是合法的版本号每个版本号至少包含1个修订号。修订号从左到右编号,下标从0开始,最左边的修订号下标为0,下一个修订号下标为1,以此类推。比较规则:一. 比较版本号时,请按从左到右的原创 2022-04-09 13:26:22 · 92 阅读 · 0 评论 -
BM20 数组中的逆序对
描述在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P mod1000000007输入描述:题目保证输入的数组中没有的相同的数字...原创 2022-04-08 17:45:20 · 316 阅读 · 0 评论 -
BM19 寻找峰值
描述给定一个长度为n的数组nums,请你找到峰值并返回其索引。数组可能包含多个峰值,在这种情况下,返回任何一个所在位置即可。1.峰值元素是指其值严格大于左右相邻值的元素。严格大于即不能有等于2.假设nums[-1] = nums[n] = −∞3.对于所有有效的 i 都有 nums[i] != nums[i + 1]4.你可以使用O(logN)的时间复杂度实现此问题吗?class Solution {public: /** * 代码中的类名、方法名、参数名已经指定,请勿修改.原创 2022-04-08 13:00:09 · 277 阅读 · 0 评论 -
BM17 二分查找-I
描述请实现无重复数字的升序数组的二分查找给定一个 元素升序的、无重复数字的整型数组 nums和一个目标值 target,写一个函数搜索 nums中的 target,如果目标值存在返回下标(下标从 0 开始),否则返回 -1class Solution {public: /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param nums int整型vector * @param target int整型 * @retur...原创 2022-03-27 14:29:11 · 27 阅读 · 0 评论 -
BM16 删除有序链表中重复的元素-II
描述给出一个升序排序的链表,删除链表中的所有重复出现的元素,只保留原链表中只出现一次的元素。思路:递归 递归 递归 递归 递归 递归====转换成子问题struct ListNode { int val; struct ListNode *next; ListNode(int _val) :val(_val), next(nullptr){}; ListNode() :val(0), next(nullptr){}; };class Solution {public:原创 2022-03-27 14:28:04 · 82 阅读 · 0 评论 -
BM6 判断链表中是否有环
描述判断给定的链表中是否有环。如果有环则返回true,否则返回false。使用快慢指针,如果有环,则快慢指针早晚会相遇。struct ListNode{ int val; ListNode* next; ListNode(int _val) :val(_val), next(nullptr){}};class Solution{public: bool hasCycle(ListNode* head) { if (head == nullptr || head-&原创 2022-03-27 14:26:45 · 55 阅读 · 0 评论 -
NC275 和为S的两个数字
描述输入一个递增排序的数组array和一个数字S,在数组中查找两个数,使得他们的和正好是S,如果有多对数字的和等于S,返回任意一组即可,如果无法找出这样的数字,返回一个空数组即可。class Solution {public: vector<int> FindNumbersWithSum(vector<int> array,int sum) { int left=0; int right=array.size()-1;原创 2022-03-27 14:24:17 · 84 阅读 · 0 评论 -
NC272 栈的压入、弹出序列
描述输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。1. 0<=pushV.length ==popV.length <=10002. -1000<=pushV[i]<=10003.pushV的所有数字均不相同class Solution ...原创 2022-03-27 14:23:31 · 164 阅读 · 0 评论 -
NC270 把数组排成最小的数
描述输入一个非负整数数组numbers,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如输入数组[3,32,321],则打印出这三个数字能排成的最小数字为321323。1.输出结果可能非常大,所以你需要返回一个字符串而不是整数2.拼接起来的数字可能会有前导 0,最后结果不需要去掉前导 0class Solution {public: static bool compare(string s1,string s2) { retu原创 2022-03-27 14:22:39 · 104 阅读 · 0 评论 -
NC262 左旋转字符串
描述汇编语言中有一种移位指令叫做循环左移(ROL),现在有个简单的任务,就是用字符串模拟这个指令的运算结果。对于一个给定的字符序列 S ,请你把其循环左移 K 位后的序列输出。例如,字符序列 S = ”abcXYZdef” , 要求输出循环左移 3 位后的结果,即 “XYZdefabc” 。是不是很简单?OK,搞定它!class Solution {public: string LeftRotateString(string str, int n) { if (n &g.原创 2022-03-27 14:21:33 · 130 阅读 · 0 评论 -
NC259 和为S的连续正数序列
描述小明很喜欢数学,有一天他在做数学作业时,要求计算出9~16的和,他马上就写出了正确答案是100。但是他并不满足于此,他在想究竟有多少种连续的正数序列的和为100(至少包括两个数)。没多久,他就得到另一组连续正数和为100的序列:18,19,20,21,22。现在把问题交给你,你能不能也很快的找出所有和为S的连续正数序列?class Solution {public: vector<vector<int> > FindContinuousSequence(int原创 2022-03-27 14:20:40 · 49 阅读 · 0 评论 -
NC156 数组中只出现一次的数(其它数出现k次)
描述给定一个长度为 n的整型数组 arr和一个整数 k(k>1) 。已知 arr 中只有 1 个数出现一次,其他的数都出现 k 次。请返回只出现了 1 次的数。思路:出现k次就不能再用异或的方法了,因为k(奇数)个相同的数异或还是得到本身。但是还是可以采用位运算的思想,因为出现k(奇数)次的数字每个位(0或者1)也是出现k(奇数)次,因此可以每一位的和能够被k整除(对k取余为0)。所以如果把每个数的二进制表示的每一位加起来,对于每一位的和,如果能被k整除,那对应那个只出现..原创 2022-03-27 14:12:27 · 148 阅读 · 0 评论 -
NC141 判断是否为回文字符串
描述给定一个长度为 n 的字符串,请编写一个函数判断该字符串是否回文。如果是回文请返回true,否则返回false。字符串回文指该字符串正序与其逆序逐字符一致。class Solution {public: /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * @param str string字符串 待判断的字符串 * @return bool布尔型 */ bool judge(string str) { for (int i =原创 2022-03-21 20:06:51 · 89 阅读 · 0 评论 -
NC140 手撕快速排序
描述给定一个长度为 n 的数组,请你编写一个函数,返回该数组按升序排序后的结果。class Solution{public: //方法1:快排:函数无返回值,用递归,注意递归出去的条件 //1.无返回值函数 //2.递归函数---先写递归结束的条件 //3.最后将基准数赋值给low指针 void qSort(vector<int>& arr, int _low, int _high) { ///递归出去的条件!!! if (_low >= _h原创 2022-03-18 13:28:29 · 180 阅读 · 0 评论 -
NC136 输出二叉树的右视图
描述请根据二叉树的前序遍历,中序遍历恢复二叉树,并打印出二叉树的右视图。先重构二叉树,再打印二叉树的右视图struct TreeNode{ int val; TreeNode* left; TreeNode* right; TreeNode(int _val) :val(_val), left(nullptr), right(nullptr){};};class Solution {public: unordered_map<int, int> index;原创 2022-03-21 16:41:24 · 452 阅读 · 0 评论 -
NC133 链表的奇偶重排
描述给定一个单链表,请设定一个函数,将链表的奇数位节点和偶数位节点分别放在一起,重排后输出。注意是节点的编号而非节点的数值。思路;定义两个头部节点odd和even, 分别表示“奇链表”和“偶链表”的头结点,每遍历一次,往对应链表尾部插入一个节点,最后“奇链表”的尾部指向“偶链表”的头部即可。时间复杂度:O(n), 遍历了一次链表,总长度为n。空间复杂度:O(1),常数个变量。struct ListNode { int val; struct ListNode *next;原创 2022-03-26 16:54:08 · 87 阅读 · 0 评论 -
NC128 接雨水问题
描述给定一个整形数组arr,已知其中所有的值都是非负的,将这个数组看作一个柱子高度图,计算按此排列的柱子,下雨之后能接多少雨水。(数组以外的区域高度视为0)思路:双指针class Solution {public: /** * max water * @param arr int整型vector the array * @return long长整型 */ long long maxWater(vector<int>& arr) { int ans =原创 2022-03-21 16:38:07 · 193 阅读 · 0 评论 -
NC127 最长公共子串
描述给定两个字符串str1和str2,输出两个字符串的最长公共子串题目保证str1和str2的最长公共子串存在且唯一。思路:最长公共子串,不是最长公共子序列,子序列可以是不连续的,但子串一定是连续的。定义dp[i][j]表示字符串str1的第i个字符结尾、str2的第j个字符结尾时,最长公共子串。注意点:需要多申请一行+一列,初始化为0,dp[i+1][j+1]=dp[i][j]+1//不累计class Solution {public: /** * longest.原创 2022-03-20 13:46:41 · 158 阅读 · 0 评论