C++单例模式 先简单介绍一下单例模式:单例模式(Singletion Pattern)是一种软件开发中的设计模式,属于创建型模式(也称工厂模式,封装对象的创建过程,使客户端可以透明地创建对象,而不需要关心对象的内部实现细节)。单例模式确保一个类只有一个实例,并提供一个全局访问点来访问这个实例。单例模式通常用于管理共享资源,如文件系统、硬件设备等,或者在。
代码随想录算法训练营Day69|自我总结 此外,对代码随想录这本书,或者网站,我也能清楚意识到,一刷的收获(很多题目对于我来说只是做了,但未理解)仍是有限的,还需要二刷、三刷可能才能真正在面对代码题时不发怵。多阅读、多敲代码、多思考。最近也在阅读一些技术书籍,希望能在技术上有新的认识。然后在这两个月的学习过程中,也给了我一些新的关于人生的认知,很多事情,不做之前就假设它的困难,只会给自己徒增烦恼,道阻且长,行则将至。这也是我2年的研究生生涯得到的,希望今年的秋招顺利,拿到心仪的offer,优于过去的自己。
代码随想录算法训练营Day58|101.孤岛的总面积、102.沉没孤岛、103.水流问题、104.建造最大岛屿 先利用BFS或DFS对边界找岛屿并将其置0,岛屿变成海洋,然后再重新遍历一遍graph,在遍历过程中计算孤岛面积即可,代码如下。虽然多次遍历,但时间复杂度和空间复杂度仍为O(N*M)。
代码随想录算法训练营Day66|Bellman_ford队列优化(SPFA算法)、Bellman_ford判断负权回路、Bellman_ford之单源有限最短路 Bellman_ford算法每次松弛都是对所有边进行松弛,但真正有效的松弛,是基于已经计算过的节点做的松弛。这句话具体看代码随想录的例子在部分节点未计算前,对其进行松弛是无意义的因此只需对上一次松弛时更新过的节点作为出发节点所连接的边进行松弛即可。利用队列记录上次松弛的时候更新过的节点。同样我们使用minDist数组,每次松弛过后,对minDist数组中改变了的节点将其存入队列中,需注意,每个节点只需加入队列一次,所以需要一个visited数组来记录入队过的元素,已经入队的元素不再重复入队。
代码随想录算法训练营Day67|Floyd算法、A*算法 本题要针对小明的计划,求计划中不同起点、不同终点的多条最短路径,与之前的dijkstra、bellman_ford等求单源最短路径不同,属于求多源最短。(多次调用单源最短路算法?这里引入Floyd算法,这里简单介绍下Floyd算法。Floyd算法,全称为Floyd-Warshall算法,是一种用于计算图中所有顶点对之间最短路径的算法。该算法由罗伯特·弗洛伊德(Robert Floyd)于1962年提出,并以弗洛伊德和斯蒂芬·沃舍尔(Stephen Warshall)的名字命名。,都可以处理。
代码随想录算法训练营Day65|dijkstra堆优化版、Bellman_ford算法 昨天对dijkstra算法有基本的认识,算法的时间复杂度为O(n^2),也在昨天内容中提到过,使用优先队列(最小堆)能够将时间复杂度降为O(nlogn),这里来讲述下如何实现。未优化的dijkstra算法需要对每个节点进行遍历,这在稠密图中是必要的,但对于稀疏图则造成了很多资源的浪费,此外,需意识到如果知道了边,则自然知道了边连接的两个节点。这里我们详细描述下这句话。使用邻接链表的方式构造图。算法的时间复杂度总的时间复杂度为O((V+E)*logV),通常情况下简化为O(E*logV)空间复杂度。
代码随想录算法训练营Day64|拓扑排序(卡码网117)、dijkstra朴素版 拓扑排序简单的说。它将图中的所有结点排序成一个线性序列,使得对于任何的边uv,结点u在序列中都出现在结点v之前,这样的序列满足图中所有的前驱-后继关系。拓扑排序通常用于任务调度、项目计划、编译依赖分析等场景,其中活动或任务之间存在依赖关系,需要确定一个合理的执行顺序。拓扑排序的。在实际应用中,拓扑排序通常和深度优先搜索或广度优先搜素结合使用。:遍历图中的所有节点,计算每个节点的入度(即有多少边指向该节点)。:创建一个空队列,将所有入度为0的节点加入队列。这些节点是没有前置依赖的节点,可以开始执行。
代码随想录算法训练营Day63|最小生成树算法prim和kruskal、kama 53.寻宝 最小生成树(Minimum Spanning Tree,MST)算法是图论中的一个重要概念,它是指在加权无向图中,找到一个边的子集,构成一个树形结构,该子集包含图中所有的顶点,同时保证所有边的权值之和最小。这个构成的树就称为最小生成树。这两种算法能够有效地找到加权无向图的最小生成树,但它们在处理图的顶点和边的关系上有所不同。普里姆算法从顶点出发,而克鲁斯卡尔算法从边出发。
代码随想录算法训练营Day62|冗余连接、冗余连接II 考虑使用并查集,逐次将s、t加入并查集中,当发现并查集中find(u)和find(v)相同时,输出u和v,表示删除的边即可。时间复杂度为O(N),空间复杂度为O(N)。
代码随想录算法训练营Day60|并查集、寻找存在的路径 并查集通常用来解决连通性问题,在我们需要判断两个元素是否在同一个集合中时,需要想到使用并查集。并查集主要有两个功能:1.将两个元素到一个集合中。2.两个元素在不在同一个集合并查集原理:以三个元素为例,将三个元素A,B,C放在同一个集合中,相当于将三个元素连通在一起,使用一个一维数组father,若father[A] = B, father[B] = C,能够构成这样的等式即说明A、B、C连通(有向连通图)。
代码随想录算法训练营Day59|110.字符串接龙、105.有向图的完全可达性、106.岛屿的周长 主要参考代码随想录目标:得到从beginStr转变为endStr所需的最少步数过程:每次变换一个字母,每次变换的结果要在strList中。对于一个图来说,相当于我们有1个起点beginStr和一个终点endStr,以及strList中的N个字符串,然后我们需要找到路径来使得beginStr变成endStr,将beginStr连接到endStr的路径即为变化的过程,我们要最小化这个过程。
代码随想录算法训练营Day57|99.岛屿数量、100.岛屿的最大面积 基本思想就是有两个矩阵,分别是图的矩阵graph和遍历过的矩阵visited,两者大小相等,但graph有原值,visited最开始全0,表示为踏足过,每次广度优先搜索会将一块岛屿全走一遍,即visited矩阵在graph的一块岛屿上的面积全部置1。利用递归来对graph中一个值为1的点四个方位的点进行递归查询,若碰到不符合条件(越界或visited数组值为1时,则自动返回),代码在整体和广度优先搜索差不多,除了使用的dfs而不是bfs,没有使用队列但使用了递归。
代码随想录算法训练营Day56|所有可达路径、797.所有可能的路径 深度优先搜索,和之前的回溯题类似。在构建图是,读入所有边,时间复杂度为O(M),在DFS是,最坏情况需要访问图中的每个节点和每天便,DFS的时间复杂度为O(N+M)。总的时间复杂度为O(N+M)。空间复杂度,用邻接矩阵来存储graph信息需要(N+1)^2(从0到N+1的矩阵),paths在图全连接的情况下,可能要存储2^(N-1)条路(1-N),path为O(N),空间复杂度为O(2^(N-1))。参考邻接数组也可以自己写写看。
代码随想录算法训练营Day55|42.接雨水、84.柱状图中最大的矩形 在上述的暴力解法中,如果我们进行调试的话,会发现每次的运行都会左右遍历一次以获取最大的leftheight和rightheight,而这有很多的计算浪费,所以我们可以在开始就从左到右,从右到左遍历一次数组,得到两个数组,分别表示每列i的leftheight和rightheight,然后用上述计算h的方法再计算一次,将算法的时间复杂度降为O(n)。对每列i进行循环,在循环中,找到该列左侧的最大高度leftHeight和该列右侧的最大高度rightHeight,该列能接到的雨水为两者较小值减去该列的高度。
代码随想录算法训练营Day53|739.每日温度、496.下一个最大元素I、503.下一个更大元素II 遍历数组元素时,比较栈顶索引和当前数组遍历索引的大小,若当前栈顶索引在数组中元素大于等于当前遍历的元素,将栈顶元素值i在ans数组中的值变为遍历的元素索引减去i.首先是遍历数组从0-2*nums.size()-1,其次对下标采取取模的操作进行栈的插入等操作,最后是本题求的是下一个大于当前元素的元素,所以不是ans数组中的不是下标,而是元素。算法的时间复杂度为O(m+n),m、n分别为两个数组的长度,空间复杂度为O(m+n),组成分别为哈希表n、ans数组m和栈n。算法的时间复杂度和空间复杂度均为O(n)。
代码随想录算法训练营Day52|647.回文子串、516.最长回文子序列 遍历字符串中的所有子串,并判断是否为回文串,若为回文串,则要返回的结果+1,最后返回所要求的结果,神奇的事居然能过,虽然时间和消耗内存都很大。从递推公式可知,当i、j相同时,递推公式是无效的,对于i、j相同的情况,我们需要手动将dp[i][j] = 1.其他值全部初始为0.算法的时间复杂度为O(n^2),空间复杂度为O((n+1)^2)。算法的时间复杂度为O(n^2),空间复杂度为O(n^2)。算法的时间复杂度为O(n^2),空间复杂度为O(n^2)。算法的时间复杂度为O(n^2),空间复杂度为O(1)。
代码随想录算法训练营Day51|115.不同的子序列、583.两个字符串的删除操作、72.编辑距离 dp[i][j]:以i-1为结尾的s的子序列中出现以j-1为结尾的t的个数。递推公式上,我们需要考虑s[i-1] == t[j-1]和s[i-1]!=t[j-1]两种情况当时,有两种情形,1是使用s[i-1]来匹配,如s:bagg和t:bag,s[2] = s[3] = 'g',可以使用s[0]、s[1]、s[2]来实现t,也能用s[0]、S[1]、S[3]来实现t,所以当s[i-1] == t[j-1]时,。,即不考虑使用s[i-1]来匹配(相当于模拟在s中删除这个元素)
代码随想录算法训练营Day50|1143.最长公共子序列、1035.不相交的线、53.最大子序和、392.判断子序列 本题和上一题718.最长重复子数组在很多方面相似,区别在与不需要连续,因此在dp数组的推导上有些改变。由于不需要连续,dp[i][j]的值针对text1和text2相同及不同这两种情况有不同的表示。首先算法的时间复杂度为O(m*n),空间复杂度为O(m*n),m和n分别代表两个序列的长度,二维数组,二维循环遍历。
代码随想录算法训练营Day49|300.最长递增子序列、674.最长连续递增序列、718.最长重复子数组 这里需要注意,但这个dp[i]怎么来的,我确实没想到。。。由于是到当前位置i为止的最长递增子序列的长度,所以当当前的nums[i]大于先前元素nums[j],。此处注意max_element返回的是最大值的迭代器,所以加*号解引用得到值的大小。算法的时间复杂度为O(n^2),空间复杂度为O(n)。
代码随想录算法训练营Day48|188.买卖股票的最佳时机IV、309.最佳买卖股票时间含冷冻期、714.买卖股票的最佳时机含手续费 至多可以购买k次,相比买卖股票的最佳时机III至多购买2次,区别在于次数不确定。每买卖一次,dp数组的第二维度加2,dp数组的第二维度为2k+1(0-2k)选最大的,所以 dp[i][1] = max(dp[i - 1][0] - prices[i], dp[i - 1][1]);所以dp[i][2] = max(dp[i - 1][1] + prices[i], dp[i - 1][2])初始化情况,当不购买时,全初始化为0,购买的情况都初始化为-prices[0],也用循环实现。最终代码。