- 博客(59)
- 收藏
- 关注
原创 C++单例模式
先简单介绍一下单例模式:单例模式(Singletion Pattern)是一种软件开发中的设计模式,属于创建型模式(也称工厂模式,封装对象的创建过程,使客户端可以透明地创建对象,而不需要关心对象的内部实现细节)。单例模式确保一个类只有一个实例,并提供一个全局访问点来访问这个实例。单例模式通常用于管理共享资源,如文件系统、硬件设备等,或者在。
2024-10-10 15:01:49
1015
原创 代码随想录算法训练营Day69|自我总结
此外,对代码随想录这本书,或者网站,我也能清楚意识到,一刷的收获(很多题目对于我来说只是做了,但未理解)仍是有限的,还需要二刷、三刷可能才能真正在面对代码题时不发怵。多阅读、多敲代码、多思考。最近也在阅读一些技术书籍,希望能在技术上有新的认识。然后在这两个月的学习过程中,也给了我一些新的关于人生的认知,很多事情,不做之前就假设它的困难,只会给自己徒增烦恼,道阻且长,行则将至。这也是我2年的研究生生涯得到的,希望今年的秋招顺利,拿到心仪的offer,优于过去的自己。
2024-07-15 12:15:16
286
原创 代码随想录算法训练营Day58|101.孤岛的总面积、102.沉没孤岛、103.水流问题、104.建造最大岛屿
先利用BFS或DFS对边界找岛屿并将其置0,岛屿变成海洋,然后再重新遍历一遍graph,在遍历过程中计算孤岛面积即可,代码如下。虽然多次遍历,但时间复杂度和空间复杂度仍为O(N*M)。
2024-07-14 15:15:21
556
原创 代码随想录算法训练营Day66|Bellman_ford队列优化(SPFA算法)、Bellman_ford判断负权回路、Bellman_ford之单源有限最短路
Bellman_ford算法每次松弛都是对所有边进行松弛,但真正有效的松弛,是基于已经计算过的节点做的松弛。这句话具体看代码随想录的例子在部分节点未计算前,对其进行松弛是无意义的因此只需对上一次松弛时更新过的节点作为出发节点所连接的边进行松弛即可。利用队列记录上次松弛的时候更新过的节点。同样我们使用minDist数组,每次松弛过后,对minDist数组中改变了的节点将其存入队列中,需注意,每个节点只需加入队列一次,所以需要一个visited数组来记录入队过的元素,已经入队的元素不再重复入队。
2024-07-14 14:45:53
524
原创 代码随想录算法训练营Day67|Floyd算法、A*算法
本题要针对小明的计划,求计划中不同起点、不同终点的多条最短路径,与之前的dijkstra、bellman_ford等求单源最短路径不同,属于求多源最短。(多次调用单源最短路算法?这里引入Floyd算法,这里简单介绍下Floyd算法。Floyd算法,全称为Floyd-Warshall算法,是一种用于计算图中所有顶点对之间最短路径的算法。该算法由罗伯特·弗洛伊德(Robert Floyd)于1962年提出,并以弗洛伊德和斯蒂芬·沃舍尔(Stephen Warshall)的名字命名。,都可以处理。
2024-07-13 17:56:13
1056
原创 代码随想录算法训练营Day65|dijkstra堆优化版、Bellman_ford算法
昨天对dijkstra算法有基本的认识,算法的时间复杂度为O(n^2),也在昨天内容中提到过,使用优先队列(最小堆)能够将时间复杂度降为O(nlogn),这里来讲述下如何实现。未优化的dijkstra算法需要对每个节点进行遍历,这在稠密图中是必要的,但对于稀疏图则造成了很多资源的浪费,此外,需意识到如果知道了边,则自然知道了边连接的两个节点。这里我们详细描述下这句话。使用邻接链表的方式构造图。算法的时间复杂度总的时间复杂度为O((V+E)*logV),通常情况下简化为O(E*logV)空间复杂度。
2024-07-11 16:00:36
808
原创 代码随想录算法训练营Day64|拓扑排序(卡码网117)、dijkstra朴素版
拓扑排序简单的说。它将图中的所有结点排序成一个线性序列,使得对于任何的边uv,结点u在序列中都出现在结点v之前,这样的序列满足图中所有的前驱-后继关系。拓扑排序通常用于任务调度、项目计划、编译依赖分析等场景,其中活动或任务之间存在依赖关系,需要确定一个合理的执行顺序。拓扑排序的。在实际应用中,拓扑排序通常和深度优先搜索或广度优先搜素结合使用。:遍历图中的所有节点,计算每个节点的入度(即有多少边指向该节点)。:创建一个空队列,将所有入度为0的节点加入队列。这些节点是没有前置依赖的节点,可以开始执行。
2024-07-10 16:48:43
711
原创 代码随想录算法训练营Day63|最小生成树算法prim和kruskal、kama 53.寻宝
最小生成树(Minimum Spanning Tree,MST)算法是图论中的一个重要概念,它是指在加权无向图中,找到一个边的子集,构成一个树形结构,该子集包含图中所有的顶点,同时保证所有边的权值之和最小。这个构成的树就称为最小生成树。这两种算法能够有效地找到加权无向图的最小生成树,但它们在处理图的顶点和边的关系上有所不同。普里姆算法从顶点出发,而克鲁斯卡尔算法从边出发。
2024-07-09 17:49:14
2073
原创 代码随想录算法训练营Day62|冗余连接、冗余连接II
考虑使用并查集,逐次将s、t加入并查集中,当发现并查集中find(u)和find(v)相同时,输出u和v,表示删除的边即可。时间复杂度为O(N),空间复杂度为O(N)。
2024-07-08 16:03:58
798
原创 代码随想录算法训练营Day60|并查集、寻找存在的路径
并查集通常用来解决连通性问题,在我们需要判断两个元素是否在同一个集合中时,需要想到使用并查集。并查集主要有两个功能:1.将两个元素到一个集合中。2.两个元素在不在同一个集合并查集原理:以三个元素为例,将三个元素A,B,C放在同一个集合中,相当于将三个元素连通在一起,使用一个一维数组father,若father[A] = B, father[B] = C,能够构成这样的等式即说明A、B、C连通(有向连通图)。
2024-07-07 15:45:07
499
原创 代码随想录算法训练营Day59|110.字符串接龙、105.有向图的完全可达性、106.岛屿的周长
主要参考代码随想录目标:得到从beginStr转变为endStr所需的最少步数过程:每次变换一个字母,每次变换的结果要在strList中。对于一个图来说,相当于我们有1个起点beginStr和一个终点endStr,以及strList中的N个字符串,然后我们需要找到路径来使得beginStr变成endStr,将beginStr连接到endStr的路径即为变化的过程,我们要最小化这个过程。
2024-07-05 18:41:03
519
原创 代码随想录算法训练营Day57|99.岛屿数量、100.岛屿的最大面积
基本思想就是有两个矩阵,分别是图的矩阵graph和遍历过的矩阵visited,两者大小相等,但graph有原值,visited最开始全0,表示为踏足过,每次广度优先搜索会将一块岛屿全走一遍,即visited矩阵在graph的一块岛屿上的面积全部置1。利用递归来对graph中一个值为1的点四个方位的点进行递归查询,若碰到不符合条件(越界或visited数组值为1时,则自动返回),代码在整体和广度优先搜索差不多,除了使用的dfs而不是bfs,没有使用队列但使用了递归。
2024-07-03 16:07:20
403
原创 代码随想录算法训练营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))。参考邻接数组也可以自己写写看。
2024-07-02 19:13:38
221
原创 代码随想录算法训练营Day55|42.接雨水、84.柱状图中最大的矩形
在上述的暴力解法中,如果我们进行调试的话,会发现每次的运行都会左右遍历一次以获取最大的leftheight和rightheight,而这有很多的计算浪费,所以我们可以在开始就从左到右,从右到左遍历一次数组,得到两个数组,分别表示每列i的leftheight和rightheight,然后用上述计算h的方法再计算一次,将算法的时间复杂度降为O(n)。对每列i进行循环,在循环中,找到该列左侧的最大高度leftHeight和该列右侧的最大高度rightHeight,该列能接到的雨水为两者较小值减去该列的高度。
2024-07-01 21:56:23
425
原创 代码随想录算法训练营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)。
2024-06-29 16:37:12
499
原创 代码随想录算法训练营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)。
2024-06-28 13:27:09
421
原创 代码随想录算法训练营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中删除这个元素)
2024-06-27 18:15:30
970
原创 代码随想录算法训练营Day50|1143.最长公共子序列、1035.不相交的线、53.最大子序和、392.判断子序列
本题和上一题718.最长重复子数组在很多方面相似,区别在与不需要连续,因此在dp数组的推导上有些改变。由于不需要连续,dp[i][j]的值针对text1和text2相同及不同这两种情况有不同的表示。首先算法的时间复杂度为O(m*n),空间复杂度为O(m*n),m和n分别代表两个序列的长度,二维数组,二维循环遍历。
2024-06-26 18:16:24
907
原创 代码随想录算法训练营Day49|300.最长递增子序列、674.最长连续递增序列、718.最长重复子数组
这里需要注意,但这个dp[i]怎么来的,我确实没想到。。。由于是到当前位置i为止的最长递增子序列的长度,所以当当前的nums[i]大于先前元素nums[j],。此处注意max_element返回的是最大值的迭代器,所以加*号解引用得到值的大小。算法的时间复杂度为O(n^2),空间复杂度为O(n)。
2024-06-25 19:47:53
551
原创 代码随想录算法训练营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],也用循环实现。最终代码。
2024-06-24 18:06:14
808
原创 代码随想录算法训练营Day46|动态规划:121.买卖股票的最佳时机I、122.买卖股票的最佳时机II、123.买卖股票的最佳时机III
之前用贪心算法做过相同的题,这次考虑使用动态规划来完成。我们已知每一天的价格price[i],则dp[i]为每一天的价格price[i]减去当初购买的价格buyprice与dp1[i-1]的较大值。。,注意要更新buyprice的价格为当前遍历过的数据中最小的值。最后返回dp[price.size()-1]。其实和贪心差不多,或者说贪心是这里动态规划的变体?算法的时间复杂度为O(n),遍历一次数组,空间复杂度同样为O(n),需要维护一个dp数组。
2024-06-23 13:29:24
847
原创 代码随想录算法训练营Day45|198.打家劫舍I、213.打家劫舍II、337.打家劫舍III
动态规划由于相邻不能偷的原则,,即为若要偷当前房屋,则比较前一个房屋dp[i-1]和不偷前一个房屋,但偷当前房屋的金额dp[i-2]+nums[i]的较大值。对dp数组的初始化,从dp数组的推导可以看出,需要初始化最开始的2个元素才能开始递推,dp[0]即只有1个房子,则只能偷那一个房子,,dp[1]则考虑第0个房屋和第1个房屋中哪个金额大,哪个金额大偷哪个,则。最后返回即为能偷到的最大金额。代码的时间复杂度为O(n),空间复杂度为O(n)。
2024-06-21 20:15:17
589
原创 代码随想录算法训练营Day44|322.零钱兑换、279.完全平方数、139.单词拆分
本题是完全背包问题考虑dp数组的推导公式,由于是计算最少硬币的个数,所以需要考虑dp[i-coins[j]+1和dp[i]的较小值。所以,其中i为遍历过程中的amout值,coins[j]为硬币的面值。已知推导公式,我们需要对dp数组赋值,由于dp推导式中求的是较小值,所以我们设定之后是对dp数组的遍历顺序,这里由于我们考虑的是最少银币个数,,这里我使用先背包后物品的遍历方式。
2024-06-20 20:02:09
615
原创 代码随想录算法训练营Day43|完全背包、518.零钱兑换II、377.组合总和IV、70.爬楼梯(进阶)
完全背包和01背包的区别在于物品的使用次数,01背包中所有物品只能使用1次,而完全背包中能够使用无限次,01背包使用逆序遍历背包,使得每个物品只能使用一次,考虑以下博客。(先遍历物品,再遍历背包,一维DP数组每次取值要用到前一轮的结果,所以使用逆序),完全背包使用正序遍历,此外,针对纯完全背包类问题(放进背包中物品的最大价值),遍历背包和物品的顺序不固定,都可以。算法的时间复杂度为O(n*m),空间复杂度为O(n)。
2024-06-19 14:34:56
989
原创 代码随想录算法训练营Day42|1049.最后一块石头的重量II、494.目标和、474.一和零
1049. 最后一块石头的重量 II - 力扣(LeetCode)考虑昨天的能否将一个数组分为两个和相等的子集,本题有类似的思路,即将左右分为左右两个和相近的子集,然后返回其差值,这里使用动态规划的话。DP数组含义,dp[j]表示能够达到的总重量为j的石头的最大重量背包容量从0到1501(根据题目要求变化)dp[j] = max(dp[j], dp[j-nums[i]] + nums[i]),j为重量,i为石头的选择与否。遍历顺序同样物品遍历在外,背包遍历在内层,且内层倒序遍历。最后考虑对最后一块石头重量的
2024-06-18 19:04:50
630
原创 代码随想录算法训练营Day41|背包问题、分割等和子集
dp数组有两维,横轴表示背包重量j(0-j),纵轴表示不同物品(0-i)。dp[i][j]的对物品i来说只有2种情况,物品i未放入或者放入,如果物品i未放入,由dp[i-1][j]可以推出,即背包容量为j,里面不放物品i的最大价值,此时dp[i][j]就是dp[i-1][j](当物品i的重量大于背包j的重量时,物品i无法放进背包中,所以背包内的价值依然和前面相同。)(参考)放物品时,
2024-06-17 20:00:10
874
原创 代码随想录算法训练营Day39|62.不同路径、63.不同路径II、343.整数拆分、96.不同的二叉搜索树
机器人位于m*n网格的左上角,机器人每次只能向下或向右移动一步(移动方向只有下和右,固定了不能回返路径)。机器人需要达到网格的右下角,需要得到共有多少条路径。思路:使用动态规划来解决,这里需要得到动态规划的dp矩阵,以及dp矩阵的推演公式。
2024-06-15 21:03:10
440
原创 代码随想录算法训练营Day38|动态规划理论基础、2.斐波那契数、3.爬楼梯、4.使用最小花费爬楼梯
动态规划(Dynamic Programming,简称DP)是一种算法设计技术,它通过将复杂问题分解为更小的子问题来解决优化问题。动态规划通常用于解决那些具有重叠子问题和最优子结构特性的问题。(可以理解为一种递推)
2024-06-14 14:40:21
2022
1
原创 代码随想录算法训练营Day37|56.合并区间、738.单调递增的数字、968.监控二叉树
和之前的思路类似,先创建一个ans二维数组,创建start和end来指明添加进入ans数组的区间下标,先对数组按照首元素排序从小到大排序后,根据当前元素是否小于下一个元素的第一个元素来决定将这个对ans数组进行增加、移动下标或改变end。具体代码如下。算法的时间复杂度为O(nlogn),空间复杂度为O(n)。代码随想录中代码。
2024-06-13 19:52:12
566
原创 代码随想录算法训练营Day36|860.柠檬水找零、406.根据身高重建队列、452.用最少的箭引爆气球
由于付账的bills数组是有顺序的,当顾客支付5美元时,我们收下5美元,当顾客支付10美元时,我们返还5美元,当顾客支付20美元时,我们可以返还一张10美元、1张5美元或者三张5美元,因此,我们需要2个变量存储拥有的5美元和10美元的数量,并根据bills数组进行变量的改变,当变量存在负值时,说明找零失败,return false。算法的时间复杂度为O(n),遍历一次bills数组。空间复杂度为O(1),只需维护2个计数器。
2024-06-12 16:10:00
412
原创 代码随想录算法训练营Day35|K次取反后最大化的数组和、134.加油站、135.分发糖果
贪心算法,将所有的负值取反后,若剩余k为偶数,则不变,得到的为最大值,若为奇数,则将取反后数组中最小的元素取反,计算得到最大值。这里使用了两次排序,第一次排序后将小于等于k次数的负数取反,得到数组中所有值求绝对值的和,之后再排一次序,则数组第一个元素为最小的元素,此时若剩余的k为奇数,则和减去2倍该元素,并返回和,否则直接返回和。算法的时间复杂度为O(nlogn),遍历一次数组,两次排序,综合为O(nlogn)。空间复杂度为O(1)。
2024-06-11 19:44:26
397
原创 代码随想录算法训练营Day32|122.买卖股票的最佳时机II、55.跳跃游戏、45.跳跃游戏II
这里我的贪心策略是,判断今天和前一天的股票差值,若差值大于0,则说明能获益,即卖出,每天都比较一次,将所有差值相加即为最终能获得的最大收益。算法的时间复杂度为O(n),仅遍历一次数组。算法的空间复杂度为O(1),只需维护常数项的空间。
2024-06-08 20:18:03
359
原创 代码随想录算法训练营day31|455.分发饼干、376.摆动序列、53.最大子序和
贪心算法,让每个饼干给到能够满足的孩子,所以需要对饼干尺寸和孩子的满足值先进行排序,然后针对每一个饼干的尺寸,挑选恰好能够满足的孩子(这里表述可能不准确,即从大到小,都选择能够满足的孩子,满足后结果返回值加1),这里选用while循环比较简单,具体代码如下。算法的时间复杂度为O(nlogn),排序需要O(nlogn),循环遍历一次需要O(n),总体需要O(nlogn)的复杂度,空间复杂度考虑排序需要的空间O(logn),其余所需的空间为O(1),所以空间复杂度应该为O(logn)。
2024-06-07 22:54:27
627
原创 代码随想录算法训练营day29|491.递增子序列、46.全排列、47.全排列II
非递减子序列,则答案的子集中,需保持下一个元素大于等于前一个元素的顺序,由于题目中指出,所有的子序列长度需大于等于2,考虑当条件为path.size()>1时,进行收获结果,且需要注意,这时不应该直接return,因为后续仍有可能存在子序列长度大于2的结果,仍需要继续遍历。此时结束的标志是单层遍历的结束。
2024-06-05 21:32:16
894
原创 代码随想录算法训练营day28|93.复原IP地址、78.子集、90.子集II
不合法的IP地址,首字母为0且长度不为1,数字超出255,递归深度为3(4个小字段构成一个合法的IP地址)没写出来,贴一下代码随想录的结果。与上题相比,需要去重,排除由于相同元素带来的相同项。和之前组合总和的去重类似。具体的东西周末再补。
2024-06-04 23:21:18
358
原创 代码随想录算法训练营Day27|39.组合总和、40.组合总和II、131.分割回文串
组合总和,这里有几点需要考虑,一是允许数字的重复使用,即相比于之前的组合,我们的start无需从索引的下一位开始,二是回溯中的返回,当总和等于target时,收获currentPath 需要返回,其次,若总和大于target时也要返回。三是考虑到要求和,尽量需要先将比较小的数字加入,所以在回溯前,考虑对数组进行排序,方便回溯。具体代码如下。算法的时间复杂度为O(n * 2^n),最坏的情况下,我们需要遍历所有可能的组合。
2024-06-03 20:59:35
546
原创 代码随想录算法训练营Day25|216.组合总和III、17.电话号码的字母组合
思路和昨日的组合题类似,但注意对回溯算法中,收获时的条件需要写对,path的长度要为k的同时,path中元素总和要为n。算法的时间复杂度,在最差的情况需,我们需要生成所有C(9,n)个组合,并且对于每个组合,都需要进行k层递归,因此时间复杂度为O(C(9,n)*n)。空间复杂度考虑递归栈,递归栈的最大深度为n,每个组合需要n个元素的存储空间,隐形空间复杂度是O(n)。
2024-06-01 17:37:29
616
原创 代码随想录算法训练营day24|回溯理论基础、77.组合
回溯算法是一种试探性的算法,用于解决组合优化问题。这类问题通常涉及在给定的候选集中找出满足特定条件的所有解。回溯算法通过深度优先遍历的方式,探索决策树的所有可能分支,从而找出所有解,就树而言,我们很容易想到递归,递归和回溯是相辅相成的。回溯法要解决的问题都能抽象成树形结构,也以此,回溯算法的基本思想是,从树的根节点开始,按某种顺序尝试所有可能的选择(例如,从左到右)。每做出一个选择,就生成一个新的节点,然后递归地继续进行选择。
2024-05-31 22:15:26
589
原创 代码随想录Day23|669.修建二叉搜索树、108.将有序数组转换为二叉搜索树、538.把二叉搜索树转换为累加树
在给定二叉搜索树的根节点root的同时,给定最小边界low和最大边界high,通过修剪二叉搜索树,使得所有节点值在[low,high]中。
2024-05-30 17:10:22
384
原创 代码随想录算法训练营Day22|235.二叉搜索树的最近公共祖先、701.二叉搜索树中的插入操作、450.删除二叉搜索树中的节点
不考虑二叉搜索树这一条件的话,普通的二叉搜索树搜索最近的公共祖先就是昨日的做法,这种做法也能解决二叉搜索树的最近公共祖先。没有用上二叉搜索树这一条件,但也能解题,但效率较低。针对二叉搜索树,我们之前有做过,当对二叉搜索树进行中序编历时,结果是一个递增的数组。即公共祖先,val值必定处于p和q之间。当从根节点向下遍历的过程中,如果遇到节点val值位于p和q之间,那么就寻找到了最近的公共祖先。具体参考代码随想录B站视频。二叉搜索树找祖先就有点不一样了!
2024-05-29 21:14:01
1962
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人