- 博客(198)
- 资源 (2)
- 收藏
- 关注
原创 Java实现多线程轮流打印1-100的数字
因此就增加一个变量flag,也是volatile修饰,用flag来控制接下来的代码是否可以被执行,比如:程序刚一启动,flag=0,说明只有线程1可以执行,其它线程在判断flag值的时候发现为0,就不会进入接下来的代码块中,而线程1就可以 i++了,执行完再修改flag的值,使得其它线程可以继续执行。思路:因为要打印1-100的数字,所以需要一个变量来记录打印到哪里,这个变量就是 i。其次,对 i 进行+1的操作并不具有原子性,而volatile也无法保证原子性,所以需要加锁来保证 i +1是原子的。
2022-11-01 11:34:50
2136
原创 力扣459 重复的子字符串
所以可以直接判断 str 中去除首尾元素之后,是否包含自身元素。则表明存在重复子串。一开始 acd (acd) ,移动一次 ac(dac)d,移动两次 a(cda)cd。acd 移动的可能:dac、cda。其实都包含在了 str 中了。比如字符串:S = acd,那么 str = S + S = acdacd。...
2022-08-06 15:58:23
156
原创 力扣120 三角形最小路径和
思路:首先尝试用自顶向下的方法求dp结果,但是从上到下每个list的长度从小到大,所以需要考虑边界值,比较麻烦,所以从下往上遍历。
2022-08-04 13:08:25
136
原创 力扣45 跳跃游戏 II
以 i = 0 为起点,nums[0]=2,说明当前能到达的最远距离是i=2,在遍历到i=2的过程中计算每个点最远的距离,取最大值,当i=2,说明已经达到了之前i=0时的最大距离,而i=1和i=2可以作为下一轮新的起点,新一轮的最远距离就是在遍历i=1和i=2时得到的最大距离。输入: nums = [2,3,1,1,4]...
2022-08-03 18:26:44
933
原创 力扣16 最接近的三数之和
思路:采用双指针left和right分别指向当前下标i的右侧区间的最左和最右,计算sum=nums[i]+nums[left]+nums[right]三数之和,和target比较,移动左右结点,取相差最小的sum作为结果返回。
2022-08-03 16:36:40
188
原创 力扣329 矩阵中的最长递增路径
思路先创建dp数组,dp[i][j]表示以matrix[i][j]为结尾的最长路径,将所有点放入list中进行排序,然后遍历list中的每个节点,访问当前节点的上下左右并比较大小得到最终值。,将matrix的每个数都作为路径的起点进行深度优先遍历,每访问一个起点,计算以它的上下左右为起点的最长路径是多少,取四个值中的最大值加一,得到当前数做起点的最大路径长度。思路遍历二维数组,首先检查下标是否正确,其次设置了pre的值,用于存储上一个结点的值,visited数组中,方法一dfs(效率更高)...
2022-08-01 17:17:08
212
原创 力扣384 打乱数组
思路遍历整个数组,从下标0开始,使用random随机得到一个数,这个数作为下标,和下标0对应的数做交换,random取随机数的过程,只能在当前下标的右侧取,可以自己和自己交换。
2022-07-31 19:14:58
140
原创 力扣135 分发糖果
思路:设学生 A 和学生 B 左右相邻,A 在 B 左边:从左往右遍历rating数组,当ratingA < ratingB 时 leftB=leftA+1。从右往左遍历rating数组,当ratingA > ratingB 时 leftA=leftB+1。将两次结果取最大值,因为这样才能同时满足以上规则。...
2022-07-31 18:44:46
142
原创 力扣440 字典序的第K小数字
sum==k时,由于nodeCount()方法是将cur也算在内的,多算了一次cur结点才导致相等,实际sum是小于k的,所以如果sum==k时说明需要到cur+1为根节点的十叉树上查找。因此利用nodeCount()方法求当前结点所在十叉树,在不超过n的情况下的节点总数sum。思路可以将字典想象成一个十叉树。...
2022-07-29 15:50:18
140
原创 力扣11 盛最多水的容器
设置两个指针,分别从数组的两边开始向中间遍历。由于盛水的多少是根据两边柱子较低的那一边的高度决定的,而为了找到能盛最多水的容器,需要找到两边最高的柱子,计算结果即可。(和接雨水的思路较为相似)...
2022-07-28 21:02:30
236
原创 力扣26 删除有序数组中的重复项
思路设置双指针,slow表示有序数组的终点,fast用于遍历整个数组,如果slow和fast指向的数值不同,向前移动slow并赋值nums[fast],最终返回slow+1表示有序数组的长度。
2022-07-28 20:38:19
159
原创 力扣59 螺旋矩阵 II
更新边界例如从左到右填完后,上边界top+=1,相当于上边界向内缩1。执行num+=1得到下一个需要填入的数字;定义当前左右上下边界。
2022-07-27 21:17:43
135
原创 力扣70 单词搜索
思路可以参考岛屿问题的解法,先遍历找到和word第一个字符相同的坐标,然后以这个坐标为起点用dfs算法遍历其上下左右的字符是否符合条件,由于遍历的时候对坐标上的字符进行修改,遍历后还需要回溯。...
2022-07-26 14:39:34
110
原创 字节高频题补充 检测循环依赖
若给定一个依赖关系是[[0,2],[1,2],[2,3],[2,4]],如图所示。入度为0的点现在只有点2,把它记录下来;重复1和2,直到图为空或没有入度为0的点。选择图中一个入度为0的点,记录下来。在图中删除该点和所有以它为起点的边。选择入度为0的节点,比如选择。解决这类问题的利器就是——如果是循环依赖,可以使用。其中,n为点的个数。.........
2022-07-25 21:14:49
1140
原创 力扣560 和为 K 的子数组
遍历nums数组,计算preSum,如果map中有preSum-k的键值对,将其出现次数加到结果上。因为如果map中已经有preSum-k,说明中间一定相邻数相加为0,或者当前遍历的数就是0。nums的第i到j项的和,有nums[i]+…+nums[j]=preSum[j]−preSum[i−1]引入前缀和的方法,定义数组preSum[x]第0项到第x项的和。满足preSum[j]−preSum[i−1]==k。计算完结果后将preSum写入map中。...
2022-07-25 20:29:53
116
原创 力扣498 对角线遍历
思路以[[1,2,3],[4,5,6],[7,8,9]]为例,三行三列,需要遍历五次,每次遍历需要先判断奇偶,然后根据题意确定遍历的方向。每次遍历结束后需要判断临界值,然后设置下一轮遍历的起点。
2022-07-18 15:16:51
142
原创 力扣283 移动零
方法一:第一次遍历将每个不为零的数存到数组前面,第二次遍历再把数组后面的部分填0.方法二:left用于指向为0的数,right遍历到不为0的就和left交换,借用了快排的思想。
2022-07-11 21:42:41
122
原创 力扣18 四数之和
思路:借鉴三数之和的思想,先固定k,判断k和k-1是否相等,然后再按照三数之和思路固定i,用j和h作为left和right,根据sum值调整j和h。
2022-06-26 11:20:18
101
原创 JUC-ThreadLocal
针对共享资源的线程安全问题,ThreadLocal可以实现资源对象的线程隔离,让每个线程各用各的资源对象,避免争用引发的线程安全问题,并且还可以实现线程内资源共享。具体原理如下图: 每个线程内又一个ThreadLocalMap类型的成员变量,用来存储资源对象。可看出ThreadLocalMap是ThreadLocal的内部静态类,而它的构成主要是用Entry来保存数据 ,而且还是继承的弱引用。在Entry内部使用ThreadLocal作为key,使用我们设置的value作为value。
2022-06-07 20:32:44
227
原创 JUC-Java内存模型(JMM)及volatile
JVM内存结构如下图:其中,方法区和堆是所有线程共享的数据区域,虚拟机栈、程序计数器和本地方法栈是线程私有的。方法区(Method Area): 方法区属于线程共享的内存区域,又称Non-Heap(非堆),主要用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据,根据Java 虚拟机规范的规定,当方法区无法满足内存分配需求时,将抛出OutOfMemoryError 异常。值得注意的是在方法区中存在一个叫运行时常量池(Runtime Constant Pool)的区域,它
2022-06-06 22:17:51
302
原创 力扣14 最长公共前缀
思路:将strs[0]的字符串作为参考,和数组中的字符串进行对比,保留公共前缀,再继续遍历剩余字符串,最后得到最长公共前缀。
2022-06-05 17:19:46
83
原创 力扣470 用 Rand7() 实现 Rand10()
简单来说就是,前半部分是为了保证与后半部分的每一位数字依次组合没有重叠。举例:以上参考: 力扣-题解因此,可以得到以上结论。反之,如果要rand4()实现rand2(),由于需要得到的数在[1,2]区间内,因此需要取余运算,再加1即可。事实上,只要中N是2的倍数,就都可以用来实现,反之,若N不是2的倍数,则产生的结果不是等概率的。要通过rand7()实现rand10(),根据Part1的推论,可以通过(rand7()-1)*7+rand7()=rand49()得到rand49(),但是49并不是
2022-06-05 10:29:00
185
原创 力扣165 比较版本号
思路:使用双指针分别指向两个字符串,只需比较当前指针指向的数字大小即可,用Integer.parseInt()解决1和001相等的问题。
2022-06-05 10:10:04
98
原创 力扣43 字符串相乘
方法一:思路:根据乘法运算的法则,遍历num2的每一位,和num1相乘,注意移位规律,最后相加可得结果。 方法二:思路:乘数 位数为 M,被乘数 位数为 N, 结果 最大总位数为 M+N。有两个指针 在 和 上游走,计算乘积,同时将乘积叠加到 的正确位置。...
2022-06-03 17:09:40
141
原创 力扣31 下一个排列
思路:如果整个数字都是降序的,说明已经到最后一个排序了,因此下一个排列就是Arrays.sort(nums),因此需要找升序的两个相邻数字,找到后将右侧的数字排序,找到比nums[i-1]大的数字,交换位置,返回这个结果。
2022-06-01 15:30:21
102
原创 力扣41 缺失的第一个正数
思路:根据题意,要找的缺失正整数一定在[1,len+1]中,len+1的情况是nums={1,2,3,4}时的结果。将数组想成hashmap数组,hash算法是nums[i-1]=i,while循环交换数组元素的位置,最后遍历数组,找到第一个不符合hash算法的位置,坐标+1就是结果,如果遍历完没有找到不符合的,返回len+1。public int firstMissingPositive(int[] nums) { int len=nums.length; for(i
2022-05-30 21:55:57
161
原创 力扣8 字符串转换整数 (atoi)
思路:需要注意几个题目要求输入的字符串表示的数超出整数范围 每轮for循环时结果的计算 if判断的顺序public int myAtoi(String s) { String str=s.trim(); char[] array=str.toCharArray(); int res=0; int sign=1; for(int i=0;i<array.length;i++){ if(i=
2022-05-30 20:43:22
155
原创 JUC-synchronized
Java采用synchronized关键字、以互斥同步的方式的解决线程安全问题,那么什么是线程安全呢?这里引用《Java并发编程实战》作者Brian Goetz给出的定义:“当多个线程同时访问一个对象时,如果不用考虑这些线程在运行时环境下的调度和交替执行,也不需要进行额外的同步,或者在调用方进行任何其他的协调操作,调用这个对象的行为都可以获得正确的结果,那就称这个对象是线程安全的。”—— Brian Goetz一、synchronized的使用(一)使用方法......
2022-05-12 17:44:53
314
原创 力扣450 删除二叉搜索树中的节点
思路:先根据二叉搜索树的性质查找目标结点,找到之后判断这个节点左右子节点是否为空,都不为空:遍历右子树的左节点,找到最左的叶子结点作为新的根节点。 public TreeNode deleteNode(TreeNode root, int key){ if(root==null) return null; if(key>root.val){ root.right=deleteNode(root.right,key); .
2022-05-10 20:09:16
144
原创 JUC-线程池
池化技术的思想主要是为了减少每次获取资源的消耗,提高对资源的利用率。线程的创建和销毁都需要映射到操作系统,因此其代价是比较高昂的。出于避免频繁创建、销毁线程以及方便线程管理的需要,线程池应运而生。线程池的优势:降低资源消耗:线程池通常会维护一些线程(数量为corePoolSize),这些线程被重复使用来执行不同的任务,任务完成后不会销毁。在待处理任务量很大的时候,通过对线程资源的复用,避免了线程的频繁创建与销毁,从而降低了系统资源消耗。 提高响应速度:由于线程池维护了一批 a...
2022-05-07 20:48:23
356
原创 Java基础-ConcurrentHashMap
Java 7 中 ConcurrentHashMap 的存储结构如下图,ConcurrnetHashMap 由很多个 Segment 组合,而每一个 Segment 内部是一个类似于 HashMap 结构的 HashEntry 数组,所以可以进行扩容。但是 Segment 的个数一旦初始化就不能改变,默认 Segment 的个数是 16 个,可以认为 ConcurrentHashMap 默认支持最多 16 个线程并发。一个ConcurrentHashMap中只有一个Segment<K,V>类
2022-05-06 21:19:14
1624
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人