- 博客(66)
- 收藏
- 关注
原创 java算法day29
如果num-1还在数组中,那说明这个num肯定不是序列的起点,如果不在数组中,那么就能肯定,是序列的起点。那么定位到了起点之后,就要从起点开始遍历整个序列,直到当前数的num+1并不存在于数组中时,可以判断遍历终止,因此还需要能够快速判断num后面的num+1是否存在于数组中。最直观的想法应该就是为了统计每个连续序列的长度,那么我们希望定位到每个连续序列的起点。这个题问的最长连续序列指的是数字依次递增的序列的最长长度。那么就是0,1,2,3,4,5,6,7,8长度为9。那么就是1,2,3,4。
2024-08-06 00:08:58
449
原创 java算法day28
情况2:将nums[i]和前面的子数组拼起来,也就是以nums[i-1]结尾的最大子数组和之和添加nums[i]。其实不用考虑中间若是多一个节点的情况,多出来的那个节点完全不会比较到,因为没有比这个元素的机会,当少1个元素的链表遍历完的时候,我循环比较的逻辑就停止了。如果f[i-1]比0还小,那说明把前面的子数组加起来是没有收益的,那么就要重起一个子数组了,此时前面这个式子值为0。初始状态那么就是dp[0],那么就是以nums[0]结尾的最长子数组,那么dp[0]= nums[0]。然后返回这个最大值。
2024-08-03 17:38:24
875
原创 java算法day27
如果你感觉某个问题有很多重叠子问题,使用动态规划是最有效的。动态规划的过程就是每一个状态一定是由上一个状态推导出来的,这一点就区分于贪心了。贪心是“直接”从局部选最优的。看到目前的各种教程,目前能看懂的动态规划思想总结就是:这三步:1、穷举法(暴力搜索)2、记忆化搜索(剪枝)3、改写成迭代形式。目前我只能一步步的做题来体会动态规划。
2024-07-31 00:04:22
1087
原创 java算法day26
拓扑排序是不断的将入度为0的节点删除(对应没有前置节点的课程)。当某课程的前置课程被学完了,那么就相当于此时变成了入度为0的节点,那么这节课可以被学(节点可以被删除)。2、不断的从队列中取出节点,将其邻节点(依赖于它的课程)的入度-1。(这里邻节点关系怎么找,回答是自己写一个邻接表,注意这个邻接表的节点上存的是该课程的后续课程组成的链表)(入度怎么记录?,因为一开始,你把图想的大一点,肯定存在着很多入度为0的节点,而第一轮肯定想着把所有入度为0的节点全删了,删完之后会暴露出新的一轮入度为0的节点。
2024-07-29 20:47:55
879
原创 java算法day25
3、然后调用DFS标记与这个陆地相连的所有陆地为已访问(用dfs就是递归,但是还是有一点BFS的影子,直接往四个方向都递归,当遇到节点是0就停下,或者节点不合法了也停下)核心:从起点出发,以起始点为中心一圈一圈进行搜索,一旦遇到终点,记录之前走过的节点就是一条最短路。这种方法是可以有效的计算岛屿数量,因为每个岛屿只会被计数一次,而与他相连的所有陆地都会在dfs的过程中被标记。那这种一圈一圈的搜索过程是怎么做到的,用了什么容器才能实现这样的遍历。回答是:用队列,栈,数组都可以。接下来是一个队列的模板。
2024-07-27 23:19:10
353
原创 java算法day23
会在遍历的过程中,不断往右的过程中,不断的去探索最大值,所以这样就满足了贪心的思想。每到一个点就更新该点所能跳到的覆盖范围,每个点的覆盖范围的计算就是i+nums[i]。但是这个cover,要取最大范围,如果每到一个点用当前点的cover,那么就有可能漏结果。因为股票就买卖一次,那么贪心的想法很自然就是取最左最小值,取最右最大值,那么得到的差值就是最大利润。贪心算法局部最优解:每次取最大跳跃步数(取最大覆盖范围),整体最优解:最后得到整体最大覆盖范围,看是否能到终点。最容易想的应该就是两个for暴力枚举。
2024-07-25 00:33:50
215
原创 java算法day22
从遍历就可以想出来,一旦startIndex>=nums.size的时候,就代表没元素扫描了,可以return了。但是实际写代码的时候,我发现这个递归条件可以不加,因为当startIndex>=nums.size的时候,for循环进不去,所以不用担心不断的进入下一层,从而爆栈。组合的思路是,前面的选了,在后面的状态中就只能往后面去选。从取2开始看,到下一层的时候取了1,那说明每到新的一层,都是从头开始取。拿到这个题,我感觉和组合的思路没有太大的区别,特点就在于,组合是要取目标节点,而子集是取所有的节点。
2024-07-23 16:52:30
332
原创 java算法day21
这个阶段所要解决的问题都是有关回溯算法。所以说解法基本上都是围绕回溯算法模板来完成。回溯算法可以这样总结,树形结构,横向遍历,纵向递归。递归出口收货结果并终止。本层递归处理完之后,对path恢复现场。
2024-07-23 15:12:09
705
原创 java算法day20
所以就按这样的思路来。一旦往下层一走刚好碰到null,那么创建新节点,这个创建的新节点刚好就符合规则,挂到了这个正确的位置上。之前我想的是我干脆弄一个pre节点,这样方便我进行插入。所以说这样的递归方式已经决定好添加的这个节点的位置了,就等着到这个地方之后进行新节点的 创建。而又由这个递归出口,决定了递归的过程中应该干什么。难点就在这种以构造左右子树的角度的题做少了,可能想得到,但是写不出。按BST的方式进行向下搜索,遇到空的位置就进行插入节点。我一开始想用的这种做法,但是pre我处理的并不好。
2024-07-22 00:25:46
311
原创 java算法day19
我第一时间想到的方法是遍历二叉树+哈希。哈希用来统计数字出现的次数。之后遍历map收集结果。利用了BST的性质,即BST的中序序列是有序序列。
2024-07-20 11:46:19
364
原创 java算法day18
昨天在后序和中序遍历构建二叉树中学到了一种构建树的新方法,每层都new一个新节点,然后对其左右子树进行递归,在返回的时候建立节点与节点之间的联系,所以返回值就是该层构建好的节点,由于是归的过程建立的联系,那么归到某一层的时候,该层返回的节点,他的下面的结构都是已经构造好了。3.递归定义子节点的范围,对于任何节点,其左子节点的值必须小于该节点的值,单要大于该节点的下界。其右子节点的值必须大于该节点的值,并且小于该节点的上界。从这个图里可以看到,上层的约束,已经带到下层去了,而且这个范围在不断的收缩。
2024-07-19 16:31:32
517
原创 java算法day17
因为在递归的过程中,要传递区间。所以需要定义几个变量:(1)HashMap inorderIndexMap用来记录中序遍历中每个值的下标索引,因为每次拿到后序中的最后一个节点,还要去确定该点在中序中的位置,正常来说我们的方法一般都是遍历去找。所以对这个查找过程我们就可以想到用hashMap来进行查找优化。该HashMap,key是节点的值,value是该节点在中序序列中的下标索引。为什么value是下标索引,因为找在中序中的位置的主要用途是用来划分左右子树的区间。
2024-07-19 00:28:48
811
原创 java算法day16
这里的正确想法是,递归左右子树,实际上是递归到最左底层后,往上回溯一层,然后才是去递归右子树。要是按我之前的做法,回溯的过程,每个右子树都是会去递归的。因此这个过程应该是不断的寻找最深节点,一旦找到更深的节点,那就应该把该点的值存下来。所以我当时就立马想到了层序遍历的做法,我在迭代每一层的元素的时候,每次把每一层的第一个元素的值存下来还是很容易的。1、左叶子点:某点的左孩子节点,其左孩子节点的左右孩子都为null,那么这个节点就是左叶子点。树左下角的值,题目给的定义就是,最后一层,最左的节点。
2024-07-17 00:03:26
408
原创 java算法day14
主函数要干的就是返回这个辅助函数的返回结果,如果辅助函数返回-1,那么,在底部就有一个位置不满足平衡二叉树的条件。平衡二叉树的判定是,每个节点都要递归的满足平衡二叉树的定义。但他不一样的点就在于,结果直接是从底层开始计算,所以只要底层返回了下面的高度,就可以避免重复的计算。这个解法有弊端,我这种解法属于自顶向下的,所以有很多的冗余计算,冗余的地方在于,我每次进入下一层,我就要调用一次计算左右子树最大高度,算一次最大高度,那就要往下递归。从底部,得出底部的信息,归的时候带上底部的信息,可以避免重复计算。
2024-07-13 17:51:29
856
原创 java算法day13
可以类比循环,在循环中我们总是要执行相同的逻辑,但是递归的特点在于,他需要在这个过程中,将计算的结果依次返给上一级。向下的过程可以发现,一直在比较左节点的左孩子是否和右节点的右孩子相等,右节点的左孩子是否和左节点的右孩子相等。唯一的变化就是判断什么时候停下来,就是处理节点的时候,如果某个节点没有叶子节点,那不就说明这层之后该节点就没有孩子嘞。一上来先粗略的考虑,这个思路是正确的,粗略的考虑就是递归计算左右子树的最小深度,每一层返回上来的时候再+1。接下来的题目几乎都用到了递归,这里就解决晕递归的问题。
2024-07-13 00:16:59
752
原创 java算法day11
所以如果调整一下前序遍历的顺序,先加左节点,再加右节点,那么得到的结果就是按根右左规则得到的。2.前序遍历是根左右,每次先处理的是中间节点,那么先将根节点放入栈中,然后将右孩子加入栈,再加入左孩子。: 确定哪些参数是递归的过程中需要处理的,那么就在递归函数里加上这个参数, 并且还要明确每次递归的返回值是什么进而确定递归函数的返回类型。与中序遍历的非递归方法相比,前序遍历的非递归实现更为直观,因为它可以直接按照遍历顺序处理节点,而不需要像中序遍历那样先到达最左节点。如果该节点有右子节点,将右子节点压入栈中。
2024-07-10 23:00:01
853
原创 java算法day10
您可以通过提供一个自定义的 Comparator 来改变 PriorityQueue 的行为。这个 Comparator 定义了元素之间的优先级关系。
2024-07-10 17:29:27
964
原创 java算法day9
添加:addFirst(E e), addLast(E e), add(E e) 删除:removeFirst(), removeLast(), remove() 查看:getFirst(), getLast()栈(Stack)风格操作: 添加:push(E e) (等同于 addFirst(E e)) 删除:pop() (等同于 removeFirst()) 查看:peek() (等同于 peekFirst())1.性能问题,Stack继承Vector,而Vector是线程安全的,所以有额外的开销。
2024-07-08 23:55:47
1076
原创 java算法day8
看到这个话要这么想,如果一个字符串s包含一个重复的字串,那么说明我可以多次移位和换行该字符串,并使其与原始字符串匹配。如果 s 是由重复子串构成的,那么在 s + s 中,原来的 s 会出现至少两次(除了首尾各少一个字符的情况)。首先题意是:给定一个非空的字符串 s ,检查是否可以通过由它的一个子串重复多次构成。如果 s 由重复的子串构成,那么在 s + s 中,去掉首尾字符后,如果 s 不是由重复子串构成的,那么在去掉首尾字符后的字符串中,去掉首尾字符后,如果原来的模式是重复的,那么仍然。
2024-07-07 23:24:47
305
原创 初识MVC
今天第一次学MVC,拿到一个练手项目。现在来记录一下学习过程。项目的背景就是个学生管理系统。我只做后端。从大的来说MVC将应用程序分为三个主要组件(部分):模型(Model)是应用程序的主要部分,包含了业务逻辑和数据。model往往代表了对象和数据库之间的数据连接。这里就对应下面的Service,dao。视图(View)是model的可视化表示。可以是图形用户界面(GUI),而在 Web应用中,view通常是指渲染数据的 HTML。控制器(Controller)是连接model和view的部分。
2024-04-29 21:42:20
1066
原创 java算法day7
Java中的字符串是不可变的,这意味着一旦一个字符串被创建,其内容就不能改变。在性能敏感的应用中,通常推荐使用StringBuilder,除非你需要在多线程环境中操作字符串。这是通过内部机制实现的,以便这两种类型的对象可以在运行时根据需要增加存储容量,以容纳更多的字符。:新的容量通常是当前容量的两倍加上2,但这可能因JVM的实现而异。如果这个新计算的容量还不足以容纳新增的数据,那么容量会增加到必要的大小以适应新增的数据。思路:遍历字符串,是数字就把number字符串插入,不是数字就把遍历的字符给插入。
2024-04-27 17:33:03
1139
1
原创 java算法day6
当求和结果过大的时候,right应该往右移动一格,这样结果就能减小。后面两个数组,也是二重for循环计算后两个数组中相加的所有结果,在这个过程中,取相加结果的负数,去哈希表中找有没有满足相加为0的组合。所以对于i的判重:必须要i>0,即在第一格的时候不用判重,所以就可以放心的写,nums[i]==nums[i-1]的时候,就可以continue进入下一轮。left的判重,left和left+1位置的元素比较,这样比较简单,主要也是担心数组越界的问题,所以left判重就要多一个条件,left
2024-04-27 14:54:33
954
1
原创 java算法day5
3.开始遍历数组,遍历的时候进行其相加的另一个值的计算,然后立即用hash进行查找,(而且题目并不限制答案中谁先谁后)。由于 String 在Java中是不可变的(immutable),任何修改 String 的操作都会生成一个新的 String 对象,而不是修改原始对象。:ArrayList 的容量可以根据需要自动增加,当添加元素使得内部数组容量不足时,ArrayList 会自动创建一个新的更大的数组,并将旧数组的内容复制到新数组中。想到统计字符串每个字符的个数,那想到的就是遍历字符串进行累加。
2024-04-24 21:44:15
765
原创 java算法day4
如果让指针从链表头部一直往前走并统计步数k,那么所有走到链表入口节点时的步数是k=a+nb,即先走a步到入口节点。但是我们不知道这个到底是多少,那么此时仍然是双指针法,考虑构建一个指针,此指针需要有这样的性质:和slow同时往前走a步后,两者在入口节点重合。之后,fast和slow同时走,两个都是每次只走一步。3.当fast指针走到f = a步时,slow指针就走到了s = a+nb,此时fast和slow在环入口重合。只要两个有相交,A,B同时往后走,A到底(null)后指回B,B到底后指回A。
2024-04-21 19:06:47
707
原创 java算法day3
此时想到cur.next = pre ,那不就完成了next后驱的翻转,但是还有个问题,如果直接cur.next = pre,那就找不到后面的结点,无法继续遍历修改链表了。所以这里再加一个tmp用于存往后遍历的位置,这个tmp的值显然就是cur的后驱:cur.next。cur指针进行判断,如果不是cur指向的不是目标元素,双方一起往后走。而pre如果是cur指目标元素后才后移,如果不是目标元素,就一起后移。前两个就已经改完了,那么现在就要到下一轮,显然temp要变到node1的位置,然后开启下一轮的逻辑。
2024-04-21 13:53:22
775
原创 java算法day2
解法仍然是二分**这个题仍然是递增,但是和上一题的区别就在于这个题有重复数字。上一题是没有的。**这个题如果还用上面那个题的思维,那么会出现一个情况,虽然插入后得到的数组看上去没问题,但实际上这个插入位置不一定是题目想要的第一个位置和最后一个位置。看下面这个图。用上一个题的思路二分下来就会有这样的问题,这个指向的位置,不一定是边界。怎么办:思路:这里我肯定是想继续往左边找,想办法找到左边界。我们只需改在。
2024-04-19 22:59:33
1155
原创 java算法day1
一旦求的和大于了target,此时就进入到了内部的滑动窗口的收缩,这个内部的滑动窗口用while来进行判断维护滑动窗口是最好的,由于求和值已经大于了target,此时就该先进行长度值的求解了,所以是先进行长度值求解,求解之后开始进行滑动窗口的收缩,收缩操作是左边slow来进行窗口大小的减小。解法:双指针,这个题的关键就在于发现一个规律,在去平方的情况下,数组中的元素一定是两边大,中间小。最后slow停留的位置,在完成最后一个元素的构造时,还会slow++,所以最后slow停在的位置就是结果值,不用去+1。
2024-04-17 20:21:33
709
原创 认证模式~
在Web应用中,Token是一个代表系统中某个实体(通常是用户会话)的加密字符串,用于在客户端和服务器间安全传递信息。Token可以存储所需的任何数据,但为了减少客户端到服务器的往返次数,它通常包含足够的信息来标识用户或会话,以及签名或其他验证数据,以确保Token的真实性和完整性。
2024-02-26 23:11:26
1264
原创 snowflake雪花算法
这个字符串代表的是Go的诞生时间(2006年1月2日15时4分5秒),你可以通过改变这个字符串中的日期和时间部分来定义自己的时间格式。雪花算法(Snowflake Algorithm)之所以适用于分布式系统,并能够被称为分布式ID生成算法,主要是因为它考虑到了分布式系统中不同节点独立生成ID的需求,通过结构化的ID格式和算法设计,确保了每个节点生成的ID既唯一又有序。这个我要解读一下,这个是go标准库的函数,用于解析时间字符串的函数,它的作用是将一个指定格式的字符串解析位time.Time类型的时间对象。
2024-02-24 22:54:26
435
原创 web通用脚手架2
这个模板的基本架构和1是一样的,唯一的一点区别就是在设计上进行了优化。因为在一盘的场景下,,而且就算改成用结构体表示,配置项和结构体还是可以完成数据更新的同步。实现数据更新同步的思想:1.仍然使用watch监控配置文件。2.然后利用里面的那个钩子函数。一旦配置文件发生修改,就立即反序列化到这个全局结构体。这样就完成了结构体的不断更新。反序列化要注意:结构体和配置文件直接要完成一个映射关系,这种映射关系一般是使用tag标签来实现。
2024-02-24 04:09:30
670
原创 较通用web脚手架模板搭建
从这里开始就接触到以后写项目的思维了。做一个web开发,那就要层次分明,要有个实现的规划,这通常也是有一个较为通用的模板的。总的来说:不同的层次有不同的模块,每个模块有必须实现的功能,我们要做的就是填充每个模块。也就是每个模块就相当于给你需求,然后你用代码去把这些需求给实现,这就是做项目的过程。
2024-02-24 02:10:20
1151
原创 gin源码实战 day2
Use 方法是 Gin 框架提供的一种方便的方式,用于为整个 Web 应用添加全局中间件。不仅可以对单个路由,还可以对路由组使用。极其方便。
2024-02-20 04:49:05
1210
原创 gin源码实战 day1
nil:表示该节点不直接关联处理函数,可能是因为它是一个参数化的路径部分,或者是未到达叶节点的中间节点。*<数字>:代表与节点关联的处理函数。数字仅为示例,实际上会是指向处理函数的指针。
2024-02-20 01:37:47
1575
原创 gorm day8
连接表可以说一个全功能的模型,支持soft Delete、钩子、更多字段,就根其他模型一样。您可以通过SetupJoinTable指定它,例如:注意:自定义连接表要求外键是复合主键或复合唯一索引ID int"`ID uint// ...// 修改 Person 的 Addresses 字段的连接表为 PersonAddress// PersonAddress 必须定义好所需的外键,否则会报错解读:这段内容解释了在GORM中如何自定义"Many To Many"关系的连接表,
2024-02-14 18:31:00
1254
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人