- 博客(64)
- 收藏
- 关注
原创 关于消息队列的一些事~
1.普通集群,在RabbitMq集群中呢,每一个节点上都会有消息队列和相应的元数据信息,然后每一个节点上还会存在其他节点的元数据信息(比如说交换机、相关路由绑定信息、队列名称、消息总数等一些无关紧要的信息),消息的内容是不会存储在其他节点上的。2.镜像集群,这种集群呢是解决了普通集群的缺点。比如说一个集群中有5个节点,然后镜像数量为2,那么每个节点除了存储自己的消息之外,还会随机选择两个节点的消息进行存储。那解决这个问题的角度就可以有两个,一个是降低生产者生产消息的速度,另一个是消费者处理消息。
2025-04-28 20:25:27
214
原创 为什么ThreadLocalMap中的ThreadLocal是弱引用类型!
如果ThreadLocal对象为null后,如果左右两边都是强引用,那这个线就不会断(强引用具有 “只要还有强引用指向对象,对象就不会被垃圾回收” 的特性);a.get()方法, 是通过遍历该线程的ThreadLocalMap 哈希表,然后找到该ThreadLocal(根据索引值去计算)对应的value,如果ThreadLocal为null的话,就会将这个entry清除掉。b.set()方法,在设置值的时候,若哈希冲突需要探查空闲位置,发现key为null的Entry,会直接复用该位置。
2025-03-20 13:04:27
775
原创 二叉树/10.16
有两个玩家玩着色游戏,A玩家先手,在二叉树上随便一个节点涂红色;涂色的规则是:每次只能涂所选节点中的邻接节点(父节点、左节点、右节点)。然后将root和RobRoot进行判断,不符合的话将root.left和root.right进行判断;当A玩家先手选出节点之后,我们可以根据该节点将树分为三部分:父节点部分、左节点部分、右节点部分。所以这里用到了两个递归,一个是在判断两棵树是否相同的时候;现在,假设你是「二号」玩家,根据所给出的输入,假如存在一个。的某个节点和这个节点的所有后代节点。若无法获胜,就请返回。
2024-10-16 09:43:53
368
原创 二叉树系列/10.14
类似于对称二叉树的思路,对称二叉树在递归的时候:是左节点的左子树和右节点的右子树进行比较;然后左节点的右子树和右节点的左子树进行比较;如果左子树的高度为-1 或者 右子树的高度为-1 证明左子树或者右子树已经不满足平衡二叉树的规则了。没有翻转的话,左节点的左子树和右节点的左子树是相同的;左节点的右子树和右节点的右子树是相同的。翻转的话,左节点的左树和右节点的右子树是相同的;左节点的右子树和右节点的左子树是相同的。递归获取到右子树的高度;平衡二叉树:任何节点的左子树和右子树的高度差的绝对值不超过 1。
2024-10-14 12:28:02
281
原创 二叉树系列 10/11
在这些路径中,只有红色和绿色的路径是伪回文路径,因为红色路径 [2,3,3] 存在回文排列 [3,2,3] ,绿色路径 [2,1,1] 存在回文排列 [1,2,1]。总共有 3 条从根到叶子的路径:红色路径 [2,3,3] ,绿色路径 [2,1,1] 和路径 [2,3,1]。(如果 A 的任何子节点之一为 B,或者 A 的任何子节点是 B 的祖先,那么我们认为 A 是 B 的祖先)(一个节点的祖父节点是指该节点的父节点的父节点。」的,当它满足:路径经过的所有节点值的排列中,存在一个回文序列。
2024-10-11 12:01:25
527
原创 二叉树系列(遍历/dfs/bfs)10.10
如果遍历到第x个节点,我们需要把值求出来,然后传给下一个节点,下一个节点*10+root.val之后,再传给下一个节点。需要用到一个队列,然后把每一层中的节点添加到队列中,遍历到最后一个节点的时候就是最右边的,添加到res中即可。2.然后,就向左右子节点遍历即可,但是要注意的是,要先判断左右子节点是否为空。,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。我们要找到根节点到叶子节点中的最短路径。最小深度是从根节点到最近叶子节点的最短路径上的节点数量。叶子节点是指没有子节点的节点。
2024-10-10 13:07:36
642
原创 图论(bfs系列)9/30
1.首先我们将所有值为1的点都加入到队列中,然后将值为0的点的值都改为-1;(为什么是step-1呢,因为在最后一次查找的时候,已经无法再向外层扩展了,但还是++,所以最后返回的时候应该再减去1)1.首先,这是一个单源点的bfs搜索题,for循环不断遍历每一次搜索能到达的点,然后把这些点加入queue队列中。多源点问题:1.首先将所有的值为1的点都加入队列中,然后将值为0的点赋值为不能达到的值。我们可以计算1到最近的0的距离的最大值。2.然后判断矩阵的规格,如果是1*1的矩阵,直接返回1;
2024-09-30 12:57:15
1120
原创 图论(dfs系列) 9/27
2.将所有的连通块找出来之后,然后枚举所有的海洋块。判断海洋块的周围有没有两个连通块(最多只能有两个连通块)。在以往的dfs搜索中,都是往四个方向去dfs;但是在这一道题中,四个方向是不行的;如果第i次是从左往右过来的,那么i+1次,就不能从右往左再过。给定一个二维数组grid,如果二维数组中存在一个环,处于环上的值都是相同的。如果不存在就返回false;1.首先找到所有的岛屿(连通块),将他们存储到map表中。如果上一次不是从左边来的,那我们就可以往左走;如果上一次不是从右边来的,那我们就可以往右走;
2024-09-27 22:32:35
1198
1
原创 图论系列(dfs岛屿) 9/26
在相同的位置处,如果矩阵2中是陆地,矩阵1中是海洋。1.出现在矩阵边缘的O定不会被包围,首先寻找未被包围的‘O’,通过dfs边缘的O,寻找连通子块。如果该节点正好是1并且没有被访问过,返回true,周围是1,满足被包围的条件。因为1是陆地,所以将两个岛屿中的1相加起来,如果为2,这就是他们重叠的陆地。2.然后剩下的O就是被包围的,将他们标记成X;淹没完不是子岛屿的岛屿,剩下的就是子岛屿的岛屿。如果值为2的岛屿中含有值为1的陆地,那么他就不是子岛屿;给定两个岛屿,看岛屿b中的岛屿是不是岛屿a中的子岛屿。
2024-09-26 13:43:45
613
原创 图论系列(dfs)9.25
我们可以遍历第一行、最后一行、第一列、最后一列的数,如果他们的值是1,就把值修改掉,然后继续dfs搜索。第一种情况:如果x在第一行或者最后一行,或者y在第一列或者最后一列(这样就意味着与走廊直接相邻了),count=-999999。我们可以将与边界相连的陆地都标记一下,因为与边界相连的陆地连通块是可以到达的。解释:8 个主题空间中,有 5 个不与走廊相邻,面积分别为 3、1、1、1、2,最大面积为 3。题目中要求不与走廊直接相邻的主题空间的最大面积。在任意次数的移动中离开网格边界的陆地单元格的数量。
2024-09-25 13:07:35
430
原创 图论系列(dfs)9/24
给定一个二维矩阵数组,1代表陆地;陆地连起来的地方叫岛屿;因此当我们向左遍历遇到的是边界,那么周长++;如果遇到的是海洋,周长++;在上一道题的基础上,不仅要求岛屿的数量,还要求每一块岛屿的面积。二叉树中不会遇到重复的结点;但是在网格中可能遇到重复的节点;仔细观察,岛屿的周长都是陆地的边和海洋以及边界处的相交;左上角一片陆地是连着的。它的周长是上面图片中的 16 个黄色的边。如果不是交界也不是陆地;题意和上面类似,只是让求岛屿的周长。直接将grid的值改为2;跟求连通块是一样的道理。
2024-09-24 13:39:03
1082
原创 图论(dfs深搜系列)9.23
第二个集合是下标为i的点的表。但是这个长度是与下标为i的点相邻的点的个数。首先找到独立的连通块以及该块中点的个数,一个连通块中的点和其他连通块都是无法互相到达的。所以假设一个连通块的点为x,一共的点为n;让求从城市1->n之间,所有路径的最小分数。如何找到独立的连通块,每次for循环,进去dfs函数,一连串的就是一个独立的连通块。在对下标为i的邻接表进行遍历的时候,有边就++;所以这道题就让我们求,以1开始的连通块中边的最小分数。1.找到独立的连通块以及块中的个数。城市构成的图不一定是连通的。
2024-09-23 13:32:57
778
原创 图论系列(dfs深搜)9.21
在dfs中,遍历每一个节点,如果他们相连并且另一个节点没有被标记过。那么标记它,并且以它作为新的节点,继续dfs。外层for循环遍历每一个节点,然后内层循环将每一个跟该节点相邻的节点都放到queue里面。主函数中,遍历每一个未标记过的节点(visited[i]==false)进行dfs深搜。将第一个节点判断完之后(也就是第一层根节点),就在visited数组中将它置为true。使用visited数组标记已经遍历过的节点。广度优先搜索,利用queue队列辅助搜索。然后第二层就是第一层结束完后队列中的节点。
2024-09-21 16:16:59
530
原创 二分系列(最小化最大值)9/19
就让你二分答案求最小。我们找出答案的范围[max,sum],然后去二分这个区间。每次拿这个mid,去check函数里面模拟他能分多少块,然后跟题目要求分的块数进行比较。如果check(nums,mid)>k(说明最大值小了,需要加大)left=mid+1。,你需要将这个数组分成。给定一个非负整数数组。个非空的连续子数组。
2024-09-19 10:54:24
611
原创 二分系列(二分答案最大值)9/15.16
给你一批机器,及其它制作一块合金所需要的不同种类金属的个数。第一台机器制作一块合金,需要一块A金属、一块B金属、一块C金属。我们对每一类机器所需要的各种种类的金属进行判断,如果仓库里面有,就不需要花钱;如果mid-index<1的,要计算有多少个1。前n项和:(mid-1+1)*(mid-1)/2+leftCount-(mid-1);根据贪心:以index为中心,向两边依次-1,直到减到1为止。如果mid-rightCount<1,先计算多少个1,xxx。
2024-09-16 12:36:03
1113
原创 二分系列(二分答案最小值)9/14
知道除数的范围之后,就可以使用二分法去查找最小的除数了。每次将mid作为参数传入check()函数中,判断当前这个除数是否满足题目要求,然后再去判断改变哪一个边界。最后返回left(left可能会不在合理的范围里面,需要判断)。需要制作m束花朵,并且每一束必须取连续的k朵花做,但是每一朵花只有在时间>bloomDay[i]才会开。首先先判断一下要求的除数的范围。如果可以根据逻辑推断出来除数的左右边界,就可以减少复杂度。,你需要选择一个正整数作为除数,然后将数组里每个数都除以它,并对除法结果求和。
2024-09-14 12:52:03
450
原创 二分系列(二分查找)9/13
那我们就要看出现次数最多的那个数,如果它出现的次数大于size/2,那么必定有剩余。由题意可得,假设左边的数字都比右边的数字与x更远,那么左边的下标也会到达size-k;如果出现的次数=
2024-09-14 08:16:31
364
原创 滑动窗口系列(三指针)9/11
有 4 个满足题目要求的子数组:[1,0,1]、[1,0,1,0]、[0,1,0,1]、[1,0,1]第一个要点:所以:0.5*ages[x]+7<=ages[y]<ages[x] 因此x必须大于14。第二个要点:遍历每一个年龄,然后确定一个范围(他可以向哪些年龄的人发送请求的范围)2.然后通过for循环枚举左边分界点,左边分界点固定之后,寻找中间分界点的范围。2.1 首先寻找最大的中间分界点:需要满足右边的区域大于等于中间的区域。2.2寻找最小的中间分界点:需要满足左边的区域小于等于中间的区域。
2024-09-12 08:33:33
608
原创 滑动窗口系列()9/10
1.如果第一个区间的左边是大于第二个区间的右边,那么没交集。2.如果第一个区间的右边是小于第二个区间的左边的,那么没交集。3.没交集的情况排除后,就是有交集的情况了。当两个数组中的元素相同时,你可以选择换一条路走。要求最后的结果是最大的。然后看左边是否<=右边,如果<=说明该区域是有效的。3.当某一个数组结束之后,另一个还没有结束,要把剩下的也加进去。1.当遇到元素相同的时候,选择该元素之前的和最大的那条路。直接将两个区间重叠,左边取最大值,右边取最小值。题目中要我们返回两个区间列表的交集;
2024-09-11 08:31:47
765
原创 滑动窗口系列(单序列双指针)9/9
在 [2,6,4,8,10,9,15] 中,我们可以看出最后一个不符合升序的数字是9,第一个不符合升序的数字是6。2.当不相等的时候,要判断typed.charAt(right)==typed.charAt(right-1),左侧正常序列的结束点:主要不出现左侧数字大于min,如果大于就要更新(此时更新的点是结束点)你只需要对 [6, 4, 8, 10, 9] 进行升序排序,那么整个表都会变为升序排序。2.1:如果碰到的是L,i<j;如果它对应的可能是你的朋友的名字(其中一些字符可能被长按),那么就返回。
2024-09-09 14:34:20
563
原创 滑动窗口系列(背向双指针)9/8
因为题目中要求子数组的两个端点需要满足i<=k<=j;然后分别向两边移动;我们的目的是得到最大的分数,即:min*(right-left+1);最优子数组的左右端点下标是 (1, 5) ,分数为 min(4,3,7,4,5) * (5-1+1) = 3 * 5 = 15。1.如果nums[left]>nums[right]的,那我们移动左指针。2.如果nums[left]<=nums[right]的,那我们移动右指针,并且更新minR;3.如果left或者right某一个到头了,那我们就更新另一边。
2024-09-08 12:23:01
759
原创 滑动窗口系列(同向双指针)/9.7
2.如果能量够的话,就换积分(这样是最划算的);其他情况就直接break(因为你的积分也不够,能量也不足以换取积分)贪心策略:如果我们使用tokens[i]值小的令牌换取积分。给定一个数组tokens[],里面装了下标为i的令牌的值,并且给定一个power,表示你的能量;相向双指针比较复杂,因为会有相同的数的情况被忽略掉。如果你的power>token[i]的,你可以利用power换取一个积分;如果红色的位置越多,那么剩余部分判断回文串的长度就小了。第一个函数中的||,是拿a还是b的前缀就行匹配。
2024-09-07 14:46:31
854
原创 滑动窗口系列(相向双指针)/9.6
从左往右遍历数组,当滑动窗口的长度==k的时候,如果此时相差值的和是更小的。最强值比较的规则为:和中位数的差值越大的最强。如果差值相同,大于中位数的强。因为要找到k个最接近的元素,所以要删除掉len-k个,那么删除掉哪些元素呢?为数组的中位数,只要满足下述两个前提之一,就可以判定。我们可以先排序,然后相向双指针,依次和中位数进行比较。因为元素的数目是固定的,所以滑动窗口的长度也是固定的。如果目标值x更接近右边,那么左边就要多删除一点。直到删除后的right-left+1==k。又因为数组是一个非递减的。
2024-09-06 13:03:51
507
原创 滑动窗口序列(单序列双指针)9/5
1.本来试图使用int max ,int min来记录滑动窗口中的最大值和最小值,然后发现当窗口左移的时候,最大值和最小值无法更新。返回其中最长的子串的长度。1.首先找到该字符重复字串1,遇到不同的字符停止,记重复子串的长度为:len1,停止时的下标为:j。大小为 2 的不间断子数组:[5,4], [4,2], [2,4]。大小为 1 的不间断子数组:[5], [4], [2], [4]。如果字符串中的所有字符都相同,那么这个字符串是单字符重复的字符串。大小为 3 的不间断子数组:[4,2,4]。
2024-09-05 14:29:24
737
原创 滑动窗口系列(不定长滑动窗口长度)9/4
使用滑动窗口的思路,当右边界增大后,仍然满足条件的时候,此时增加的有效答案有:right-left+1.为什么呢?然后左边界移动,移动的时候数量要改变,如果数量==0,种类也要改变。8 个乘积小于 100 的子数组分别为:[10]、[5]、[2]、[6]、[10,5]、[5,2]、[2,6]、[5,2,6]。完全子数组有:[1,3,1,2]、[1,3,1,2,2]、[3,1,2] 和 [3,1,2,2]。因为当更新右边界后,可能该滑动窗口不是满足条件的,所以在更新左边界之后,再计算有效的子数组。
2024-09-04 12:28:49
1318
原创 滑动窗口系列(不定长滑动窗口长度)9/3
剩下的部分可能在一个数组中,也可能分布在两个数组中,所以用剩下的target(target-sum(nums))在长度为2*nums.length的数组中去找最短子数组。给定一个数组nums,nums中的元素按照顺序循环放在infinite_nums中,然后在infinite_nums中找到一个最短子数组,和为target。2.当不替换子串中字母出现的次数是<=k次的,说明替换子串是符合题意的;不替换子串中某个字母出现的次数一定要<=k次,因为如果出现的次数>k次,那么就要出现在替换子串中了。
2024-09-03 20:47:52
661
原创 滑动窗口系列(不定长滑动窗口长度) 9/2
移动right的时候,需要更新costK,costK=(nums[right]-nums[right-1])*(right-left);逆向思维就是:题目中是否存在一段子串满足字符出现最多的次数为:count[0]-k,count[1]-k,count[2]-k。每次遍历到一个字符,就将出现的次数-1(还可以出现多少次),如果出现<0的情况,左边界就要改变了。每次操作的时候,移除左边和右边的元素,使得移除元素之和=x。给定一个数组nums,求子数组中删除k个元素后,所有元素都相等,返回相同元素的最大个数。
2024-09-02 13:22:16
1286
原创 滑动窗口系列(不定长滑动窗口长度) 9/1
给定一个字符串 ,请你找出其中不含有重复字符的 最长子串 的长度。输入: s = "abcabcbb"输出: 3 解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。思路:不定长的滑动窗口长度,其中windowSize=无重复字符的最长字串的长度;那么如何得到最长字串的长度?使用哈希表+while循环遍历如果遍历到的字母在哈希表中存在,此时字串中出现重复字符;此时我们就要移动left改变滑动窗口的左边界;使得哈希表中不再出现s.charAt(right);因为新的字符串的开始一
2024-09-01 13:04:48
742
原创 滑动窗口系列(定长滑动窗口长度) 8/30
k>0,开始进行循环遍历数组中的每一个数字,当right-left+1==k或者right+len-left+1==k的时候,res[(left-1)%k]==sum,循环的条件为index<nums.length+k-1(要使数组上每一个位置都有新的和)对数组遍历循环,当窗口的长度==k的时候,判断平均值是否大于等于阈值,如果大于等于res++;如果k>0,数组中下标为index的值为后k位数字(>nums.length-1就返前来)的和;给定一个nums数组,计算中所有整数数对中 数位差的个数之和;
2024-08-30 22:42:48
746
原创 算法学习day32
2.如果遍历到的数字可以和放一个数字构成一个有效的大写字母的ASCII值,是对dp[i+1]有用的,(这个有用是指多了dp[i-1]种分割方法)那么dp[i+1]+=dp[i-1];现在1有与3,5相乘的资格,2有与2,3,5相乘的资格,但是2×3和2×5是没必要比较的,因为有比它更小的1可以同3,5相乘,所以我们只需要比较1×3,1×5,2×2。即n=2*x+3*y+5*z。如果nums[i]==nums[i-1]&&nums[i-1]==nums[i-2] 那么dp[i]+=dp[i-1]+1;
2024-08-12 18:10:44
1138
原创 算法学习day30
/要求最小值,dp[i-1][1](下标到i-1的最大值)*nums[i]dp[i][0]=Math.min(nums[i],dp[i-1][0]*nums[i]);//要求最大值,dp[i-1][0]*nums[i]2.递推公式:dp[i]=Math.max(dp[i],Math.max(i*j,i*dp[j]));
2024-08-07 17:15:11
998
原创 算法学习day28
举个例子理解一下:假如按照升序排列后为:(5,5),(6,6),(7,2)(7,1)(8,3),(9,4)。4.envelopes[i][1]=1, 1小于6,给1寻找合适的位置,1<2,因此tails[0]=1;5.envelopes[i][1]=3,3小于6,给3寻找合适的位置,3<6,因此tails[1]=3;2.envelopes[i][1]=6, 6大于5,tails[1]=6,size=2;1.envelopes[i][1]=5, 集合为空,tails[0]=5 size=1;
2024-08-03 21:43:16
1944
原创 算法学习day26(滑动窗口)
其实就是在不断寻找最长滑动窗口长度的过程。滑动窗口的大小只能增大不能减小。1.找中间值3。分成两段:1->2\ 3->4->52.中间值作为新的头结点反转5->4->3左边拿一个 右边拿一个。
2024-08-01 21:52:14
886
原创 算法学习day25
当遇到 map.containsKey(s.charAt(right))的时候,说明遇到重复子串了,此时更新一下当前子串的长度,然后将左边起始位置右移,继续遍历。要判断s2是否包含s1的排列,顺序不一样也算包含,直观的想法:就是将s1所有的排序都列出来,然后判断在s2中是否存在,存在一种就返回true;两道题的做法都是类似的,先固定一个起始位置,然后在剩余的范围里面使用双指针进行遍历(前提是要先对数组进行排序),遍历的过程中找符合条件的结果。使用双指针进行遍历,每次左边固定,右边寻找无重复子串的最长子串。
2024-08-01 08:18:57
1373
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人