笔试混子准备
文章平均质量分 95
97Marcus
盼望成为offer收割机的菜花
展开
-
代码随想录1刷—单调栈篇
如果当前遍历的元素(柱子)高度等于栈顶元素的高度,要跟更新栈顶元素,因为遇到相相同高度的柱子,需要使用最右边的柱子来计算宽度。如果当前遍历的元素(柱子)高度小于栈顶元素的高度,就把这个元素加入栈中,因为栈里本来就要保持从小到大的顺序(从栈头到栈底)。单调栈的本质是空间换时间,因为在遍历的过程中需要用一个栈来记录右边第一个比当前元素高的元素,优点是只需要遍历一次。每一列雨水的高度,取决于,该列左侧最高的柱子和右侧最高的柱子中矮的柱子的高度。的情况,此时满足递增栈(栈头到栈底的顺序),所以直接入栈。......原创 2022-07-20 00:05:47 · 1749 阅读 · 1 评论 -
代码随想录1刷—动态规划篇(四):编辑距离
初始化两个指针 i 和 j,分别指向 s 和 t 的初始位置。每次匹配成功则 i 和 j 同时右移,匹配 s 的下一个位置,匹配失败则 j 右移,i 不变,尝试用 t 的下一个字符匹配 s。最终如果 i 移动到 s 的末尾,就说明 s 是 t 的子序列。动态规划编辑距离的入门题目,从题意中可以发现,只需要计算删除的情况,不用考虑增加和替换的情况。1、dp[i][j]dp[i][j]dp[i][j] 表示以下标i−1i-1i−1为结尾的字符串sss,和以下标j−1j-1j−1为结尾的字符串ttt,相同子序原创 2022-07-13 19:52:08 · 292 阅读 · 0 评论 -
代码随想录1刷—动态规划篇(三)
1、2、决定 dp[i]dp[i]dp[i] 的因素就是第 iii 房间偷还是不偷。然后 dp[i]dp[i]dp[i] 取最大值,即3、递推公式的基础就是 dp[0]dp[0]dp[0] 和 dp[1]dp[1]dp[1] ,4、 dp[i]dp[i]dp[i] 是根据 dp[i−2]dp[i-2]dp[i−2] 和 dp[i−1]dp[i-1]dp[i−1] 推导出来的,那么一定是213. 打家劫舍 II和 198.打家劫舍 的唯一区别就是 房屋成环了。对于一个数组,成环的话主要有如下三种情况:[外原创 2022-07-12 20:39:13 · 341 阅读 · 0 评论 -
代码随想录1刷—动态规划篇(二):背包问题
有nnn件物品和一个最多能背重量为www的背包。第iii件物品的重量是weight[i]weight[i]weight[i],得到的价值是value[i]value[i]value[i] 。每件物品只能用一次,求解将哪些物品装入背包里物品价值总和最大。每一件物品其实只有两个状态,取或者不取,所以可以使用回溯法搜索出所有的情况,那么时间复杂度就是O(2n)O(2^n)O(2n),这里的nnn表示物品数量。所以暴力的解法是指数级别的时间复杂度。进而才需要动态规划的解法来进行优化。为便于理解,先规定背包最大重量为原创 2022-07-09 21:11:44 · 644 阅读 · 0 评论 -
代码随想录1刷—动态规划篇(一)
核心:动态规划中每一个状态一定是由上一个状态推导出来的。1、的定义为:第个数的斐波那契数值是2、状态转移方程;3、初始化:4、是依赖 和 ,那么遍历的顺序一定是从前到后遍历的、5、当为的时候,数组应该是数列:如果代码写出来,发现结果不对,就把dp数组打印出来看看和推导数列是否一致。优化当然可以发现,实际上只需要维护两个数值就可以了,不需要记录整个序列。递归解法70. 爬楼梯第三层楼梯的状态可以由第二层楼梯 和 到第一层楼梯状态推导出来,所以可以用动态规划。1、: 爬到第层楼梯,有种方法2、3、,原创 2022-07-09 12:11:56 · 718 阅读 · 0 评论 -
代码随想录1刷—贪心算法篇(二)
局部最优:当气球出现重叠,一起射,所用弓箭最少。全局最优:把所有气球射爆所用弓箭最少。如果真实的模拟射气球的过程,应该射一个,气球数组就remove一个元素,这样最直观,毕竟气球被射了。但仔细思考一下就发现:为了让气球尽可能的重叠,需要对数组进行排序。如果把气球排序之后,从前到后遍历气球,被射过的气球仅仅跳过就行了,没有必要让气球数组remote气球,只要记录一下箭的数量就可以了。如果气球重叠了,重叠气球中右边边界的最小值 之前的区间一定需要一个弓箭。注意题目中说的是:满足,则该气球会被引爆。那么说明两个气原创 2022-07-08 19:29:33 · 259 阅读 · 0 评论 -
代码随想录1刷—贪心算法篇(一)
贪心的本质是选择每一阶段的局部最优,从而达到全局最优。贪心算法一般分为如下四步:贪心没有套路,没有模板,刷题或者面试的时候,手动模拟一下感觉可以局部最优推出整体最优,而且想不到反例,那么就试一试贪心。为了满足更多的小孩,就不要造成饼干尺寸的浪费。大尺寸的饼干既可以满足胃口大的孩子也可以满足胃口小的孩子,那么就应该优先满足胃口大的。这里的局部最优就是大饼干喂给胃口大的,充分利用饼干尺寸喂饱一个,全局最优就是喂饱尽可能多的小孩。可以尝试使用贪心策略,先将饼干数组和小孩数组排序。然后从后向前遍历小孩数组,用大饼干原创 2022-07-08 15:10:20 · 541 阅读 · 0 评论 -
代码随想录1刷—回溯篇(二)
491. 递增子序列本题求自增子序列,是不能对原数组进行排序的,所以不能使用之前的去重逻辑!同一父节点下的同层上使用过的元素就不能在使用了。利用数组去重程序运行的时候对unordered_set 频繁的insert效率是比较低的,因为unordered_set需要做哈希映射(也就是把key通过hash function映射为唯一的哈希值),相对来说比较费时间,而且每次重新定义set,insert的时候其底层的符号表也要做相应的扩充。而本题的数值范围[-100,100],所以完全可以用数组来做哈希。数组原创 2022-07-06 22:56:31 · 356 阅读 · 0 评论 -
代码随想录1刷—回溯篇(一)
回溯是递归的副产品,只要有递归就会有回溯。回溯的本质是穷举,穷举所有可能,然后选出我们想要的答案,如果想让回溯法高效一些,可以加一些剪枝的操作,但也改不了回溯法就是穷举的本质。虽然回溯法是个非常低效的办法,但一些问题只能用回溯来解决。还没有更高效的解法。回溯法一般是在集合中递归搜索,集合的大小构成了树的宽度,递归的深度构成的树的深度。77. 组合每次从集合中选取元素,可选择的范围随着选择的进行而收缩,调整可选择的范围。(因此需要一个参数,为int型变量startIndex,这个参数用来记录本层递归的中原创 2022-07-06 15:57:36 · 187 阅读 · 0 评论 -
代码随想录1刷—二叉树篇(三)
最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”注意求最小公共祖先,需要从底向上遍历,而二叉树只能通过后序遍历(即:回溯)实现从底向上的遍历。在回溯的过程中,因为要使用递归函数的返回值(也就是代码中的left和right)做逻辑判断,所以必须要遍历整棵二叉树,即使已经找到结果了,依然要把其他节点遍历完。要理解如果返回值left为空,right不为空的情况下,为什么返回ri原创 2022-07-06 00:07:57 · 166 阅读 · 0 评论 -
代码随想录1刷—二叉树篇(二)
如果是模拟前中后序遍历就用栈,如果是适合层序遍历就用队列;其他情况:先用队列试试行不行,不行就用栈。遍历+记录遍历的节点数量就可以了。利用完全二叉树性质的求法完全二叉树只有两种情况,情况一:就是满二叉树,情况二:最后一层叶子节点没有满。对于情况一,可以直接用 2^树深度 - 1 来计算,注意这里根节点深度为1。对于情况二,分别递归左孩子,和右孩子,递归到某一深度一定会有左孩子或者右孩子为满二叉树,然后依然可以按照情况1来计算。完全二叉树(一)如图:完全二叉树(二)如图:可以看出如果整个树不是满二叉树,原创 2022-07-05 17:17:19 · 1829 阅读 · 0 评论 -
代码随想录1刷—二叉树篇(一)
之前提到过优先级队列其实是一个堆,堆就是一棵完全二叉树,同时保证父子节点的顺序关系。二叉搜索树是有数值的了,二叉搜索树是一个有序树。下面这两棵树都是搜索树它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。最后一棵 不是平衡二叉树,因为它的左右两个子树的高度差的绝对值超过了1。C++中map、set、multimap,multiset的底层实现都是平衡二叉搜索树,所以map、set的增删操作时间时间复杂度是lognlog nlogn,注意我这里没有说unordered原创 2022-06-29 15:06:19 · 303 阅读 · 0 评论 -
代码随想录1刷—栈和队列篇
栈和队列是STL(C++标准库)里面的两个数据结构。C++标准库是有多个版本的,要知道我们使用的STL是哪个版本,才能知道对应的栈和队列的实现原理。三个最为普遍的STL版本:接下来介绍的栈和队列也是SGI STL里面的数据结构, 知道了使用版本,才知道对应的底层实现。栈提供push 和 pop 等等接口,所有元素必须符合先进后出规则,所以栈不提供走访功能,也不提供迭代器(iterator)。 不像是set 或者map 提供迭代器iterator来遍历所有元素。**栈是以底层容器完成其所有的工作,对外提供统一原创 2022-06-26 18:40:06 · 372 阅读 · 0 评论 -
代码随想录1刷—字符串篇
的两种实现方式交换数值:位运算:541. 反转字符串 II剑指 Offer 05. 替换空格如果从前向后填充就是O(n^2)的算法了,因为每次添加元素都要将添加元素之后的所有元素向后移动。其实很多数组填充类的问题,都可以先预先给数组扩容带填充后的大小,然后在从后向前进行操作。这么做有两个好处:151. 颠倒字符串中的单词剑指 Offer 58 - II. 左旋转字符串题外话:和到底有什么不一样?本质上单独拿出来说,和的意思是一样的,就是。如果当做运算符来说,如果和这样的原创 2022-06-26 12:54:45 · 417 阅读 · 0 评论 -
代码随想录1刷—哈希表篇
哈希表是根据关键码的值而直接进行访问的数据结构。一般哈希表都是用来快速判断一个元素是否出现集合里。当我们遇到了要快速判断一个元素是否出现集合里的时候,就要考虑哈希法。但是哈希法也是牺牲了空间换取了时间,因为我们要使用额外的数组,set或者是map来存放数据,才能实现快速的查找。如果在做面试题目的时候遇到需要判断一个元素是否出现过的场景也应该第一时间想到哈希法!将学生姓名映射到哈希表上就涉及到了hash function ,也就是哈希函数一般hashcode是通过特定编码方式,可以将其他数据格式转化为不同的数原创 2022-06-25 17:06:12 · 373 阅读 · 0 评论 -
代码随想录1刷—链表篇
通过自己定义构造函数初始化节点:使用默认构造函数初始化节点:所以如果不定义构造函数使用默认构造函数的话,在初始化的时候就不能直接给变量赋值!注意:C++里最好是再手动释放这个D节点,释放这块内存。双指针递归707.设计链表206.反转链表双指针递归24.两两交换节点递归19.删除链表的倒数第N个节点双指针的经典应用,如果要删除倒数第n个节点,让fast移动n步,然后让fast和slow同时移动,直到fast指向链表末尾。删掉slow所指向的节点就可以了。注意几个细节:1原创 2022-06-24 19:27:41 · 393 阅读 · 0 评论 -
代码随想录1刷—数组篇
数组为有序数组数组中无重复元素(因为一旦有重复元素,使用二分查找法返回的元素下标可能不是唯一的)如果题目描述满足如上条件,可想一想是不是可以用二分法了。双指针法双指针法(快慢指针法):通过一个快指针和慢指针在一个for循环下完成两个for循环的工作,在数组和链表的操作中是非常常见的。此外还有双向指针法:两个指针分别从前后开始进行遍历并进行操作。滑动窗口(参考labuladong算法小抄)所谓滑动窗口,就是不断的调节子序列的起始位置和终止位置,从而得出我们要想的结果。先思考如下问题:1、当移动 扩原创 2022-06-23 15:31:10 · 258 阅读 · 0 评论 -
代码随想录1刷—算法性能分析摘记
大家可能会发现内存对齐岂不是浪费的内存资源么?是这样的,但事实上,相对来说计算机内存资源一般都是充足的,我们更希望的是提高运行速度。编译器一般都会做内存对齐的优化操作,也就是说当考虑程序真正占用的内存大小的时候,也需要认识到内存对齐的影响。想要算出自己程序会占用多少内存就一定要了解自己定义的数据类型的大小,如下:注意图中有两个不一样的地方,为什么64位的指针就占用了8个字节,而32位的指针占用4个字节呢?1个字节占8个比特,那么4个字节就是32个比特,可存放数据的大小为2^32,也就是4G空间的大小,即:可原创 2022-06-23 14:20:26 · 452 阅读 · 0 评论