- 博客(20)
- 收藏
- 关注
原创 Java并发编程知识点梳理
释放许可证成功之后,同时会唤醒同步队列中的一个线程。被唤醒的线程会重新尝试去修改 state 的值 state=state-1 ,如果 state>=0 则获取令牌成功,否则重新进入阻塞队列,挂起线程。注意:sleep()方法和wait()方法都可以停止对应线程的运行,sleep方法位于Thread类中,wait()方法位于Object类中。:最佳线程数 = N(CPU 核心数)∗(1+WT(线程等待时间)/ST(线程计算时间)),其中 WT(线程等待时间)=线程运行总时间 - ST(线程计算时间)。
2023-08-01 23:27:54
220
1
原创 代码随想录一刷总结
首先,在知识积累方面,系统学习了链表及其相关的应用,比如K个节点一组翻转链表,两两交换单向链表的节点,翻转单项链表,链表成环的判断以及链表相交的入口。在数组相关题目方面,运用比较多的依然是双指针的技巧。这让我们养成每日坚持学习与总结的习惯,感觉每天都过得很充实,不仅学习到了数据结构与算法得知识,也养成了坚持学习的习惯,这对于以后的学习生涯和职业生涯都是大有裨益的。代码随想录一刷的完成意味着一个新的里程的开始,后面我需要温故知新,每天坚持复习与做题,保持做题的感觉,希望自己在笔试的过程中取得满意的成绩吧。
2023-07-25 11:10:42
561
原创 额外题目练习
注意:利用二分查找以及循环不变量(区间左闭右闭)的思想。//寻找target的左边界//注意循环不变量:区间都是左闭右闭}else{//寻找target的有右边界//注意循环不变量:区间都是左闭右闭}else{return res;return res;return res;
2023-07-25 00:38:06
118
原创 单调栈及其应用
当遍历到当前元素比栈顶元素大时,说明此时的栈顶元素就是中间位置,而当前元素就是右边位置,栈顶元素的后面一个元素就是左边位置。注意:在求中间元素的左边位置对应元素的时候,应该将中间位置的下标(此时的栈顶元素pop(),当前元素比栈顶元素对应的值小时,则说明栈顶元素是中间位置,栈顶元素的右边一个元素(如果存在的话)是左边位置(即左边第一个小于栈顶元素的元素下标),当前元素是右边位置(即右边第一个小于栈顶元素的下标)。若当前遍历的元素等于栈顶的元素,也是将当前元素直接入栈,不做记录结果的过程。
2023-06-27 22:32:29
105
原创 动态规划之最长递增子序列
dp[i] = max(dp[j] + 1, dp[i]) 因为dp[j] + 1中的dp[j]并非是在前一个已经加1的dp[j]的基础之上再加上1。否则,dp[i][j] = Math.min(Math.min(dp[i - 1][j] + 1, dp[i][j - 1] + 1), dp[i - 1][j - 1] + 1);否则的话:dp[i][j] = Math.min(dp[i - 1][j] + 1, dp[i][j - 1] + 1, dp[i - 1][j - 1] + 2);
2023-06-26 16:51:07
1741
1
原创 动态规划之买卖股票的最佳时机
5.最后返回dp[prices.length - 1][1], dp[prices.length - 1][2], dp[prices.length - 1][3]中的最大值。dp[i][1]表示第i天不持有(有可能是第i天卖出,也有可能是第i天之前就已经卖出了)所能获取的最大金额。dp[i][1] + prices[i]:表示第i天才没有持有股票。由于可以多次买卖,所以第i天买入股票时的本金不再是0了,而是dp[i - 1][1]。dp[0][0]: -prices[0] (因为最开始就只有0元)
2023-06-20 23:02:29
327
1
原创 动态规划之打家劫舍
最后返回的根节点的dp数组携带了遍历其左右子树后所能获取的最大值的情况。同时其也考虑了偷与不偷根节点所能获得的最大值的情况。定义dp数组:dp[0]表示不偷当前节点所能获得的最大值,dp[1]表示偷当前节点所能获得的最大值。定义dp数组:考虑下标i(可以偷第i家也可以不偷,只是考虑),则dp[i]表示考虑第i家以及按照规则之前所能够偷到的最大的金额。1.考虑下标i: dp[i - 2] + nums[i];从i为2开始遍历,直到遍历至nums数组的最后一个元素。2.不考虑下标i:dp[i - 1]
2023-06-18 17:44:33
33
原创 动态规划之背包问题
关键:尽量把石头分成重量相似的两堆。//定义以及初始化dp数组dp[0] = 0;//定义递推公式及遍历顺序i++){j--){
2023-06-17 23:18:20
85
原创 动态规划及其应用(1)
动态规划五部曲:1.明确动态规划数组(dp)的下标及其元素的含义;2.明确动态规划数组元素之间的递推关系;3.明确动态规划数组的初始值;4.明确遍历顺序(从前往后或从后往前);5.打印动态规划数组,以便检查代码逻辑是否正确。
2023-06-14 10:57:20
459
原创 贪心算法及其应用
局部最优可以退出整体最优,并且找不出反例,则可以考虑贪心算法。代码随想录leetcode 376 摆动序列本题分为三种情况:1.上下坡中有平坡;2.只有首尾两个元素;3.单调坡中有平坡;(prediff只是记录摆动出现的时候初始的坡的方向)假设最右侧有坡度,故初始result = 1.leetcode 53 最大子数组和若连续和为负数,则立刻抛弃,选择下一个数作为起始位置。以下暴力解法超时:利用贪心:leetcode 122 买卖股票的最佳时机leetcode 55 跳跃游戏利
2023-06-11 21:19:13
717
原创 二叉搜索树节点的插入和删除及其他应用
本题采用后续遍历,若上一层递归函数中的传入下一层函数的左子树与右子树的返回值都是true,则说明本层的节点是目标节点的公共祖先(目标节点存在于其左右子树之中)注意:删除二叉树中的一个节点,应将待删除节点的左子树或右子树连在待删除节点的父节点上。利用求累计数组的双指针的思想。本题也采用后序遍历,注意利用二叉搜索树的排序性质即可。###leetcode 450 删除二叉搜索树中的节点。本题思路是递归的选取数组的中间节点作为根节点去构造。插入的节点一定是连在原树的叶子节点上。1.删除节点就是叶子节点。
2023-06-03 17:49:49
49
原创 栈和队列刷题记录
Java栈栈是vector的子类,而vector可理解为容纳不同元素类型的可变长数组。常用的方法:empty() peek() push() pop()以及search()。Java队列LinkedList类实现了Queue接口,因此我们可以把LinkedList当成Queue来用。常用的方法:size() offer()以及 peek()/element()
2023-06-02 13:18:57
66
原创 【二叉树的遍历以及有关题目】
比如当遍历到某一节点的左子树时,其局部变量depth会加1,当其左子树遍历完成时,若depth不减去1,那么遍历右子树的时候,其计算起始点便和左子树根节点不再同一位置,而是多加了1,所以要回溯减1。再定义一个size,用来记录当前层的节点的个数,以便区分队列中有哪些节点是属于当前节点的。5.切后序数组(用中序数组的左区间的大小来切后序数组,同样得到后序数组中左区间的节点,剩下的便是后续数组中右区间的大小)注意将结果数组定义到执行函数的外部作为类的成员属性,不然每次递归都要将前面的值清空。
2023-05-31 23:54:15
156
原创 KMP算法及其应用
需要注意的是,当去除原字符串的多余空格之后,要利用System.arraycopy()resize数组。利用移动匹配的方法:ss = s + s,去掉ss的第一位和最后一位的字符后,再ss.find(s)。由于next数组中的值就是包含i在内的子串之中的最长相等前后缀的长度,故当s[j] == s[i]时,next[i] = j。求next数组:分为四步:1.初始化 2.前后缀不相同的情况 3.前后缀相同的情况 4.更新。j:表示前缀末尾,同时也表示包含i在内的子串之中的最长相等前后缀的长度;
2023-05-29 00:57:58
178
1
原创 哈希表及其应用
最后将结果转换成数组输出,数组的initCapacity可以由容器的.size()方法获取。注意C++中提取字符串的每个字符可以用字符串名[i]的方法,而Java中要用字符串名.charAt(i)的方法。对b和c的去重一定要放在已经获得一个结果之后的代码中,否则会遗漏{0,0,0,0,0}这种情况。注意用Java进行map[a+b]++操作时(将对应数值的出现次数加1),利用变量val赋值时要用++val(具体见代码)。本题也使用HashMap,其中key存放数值,value存放该数值出现的次数。
2023-05-28 16:00:23
358
原创 链表及其应用
注意循环退出条件:cur.next!= null (链表节点数为偶数);= null(链表节点数为奇数)。否则会出现空指针异常(null.next 是错误的)。注意cur指针一定要先指向待交换的两个节点的前一个节点的位置。并且利用虚拟头节点。本题采用快慢指针的思想判断单链表是否存在环。注意循环的终止条件是。
2023-05-27 18:21:52
77
1
原创 链表及其应用(2)
注意虚拟头节点的应用,创建一个虚拟头节点并指向原链表本身的head节点。利用pre和cur指针,遍历链表并进行链表节点的删除操作。当符合删除条件时,只移动cur指针;当不满足条件时,pre和cur指针同时前移一个节点。函数最后返回虚拟头节点的next节点。注意循环变量要在循环体内改变,不然会形成死循环。注意在前一个循环体中修改的指针的位置,其是否还适合于下一次循环的起始位置。注意addAtTail()方法在链表为空时的特例的处理方式。注意虚拟头节点的应用。定义三个指针:pre,cur,next。
2023-05-27 12:16:05
80
1
原创 控制循环不变量方法的应用
的规则,则遍历第一圈时的偏置量offset为1,往后每增加一圈,offset的值也相应增加1。这里的count为矩阵中各元素的值,其大小也随循环的次数加1。采用滑动窗口的思想,滑动窗口的终止位置是j,起始位置是i,注意要用while循环而不能使用if来判断子数组元素之和大于或等于target,否则就只能将i向前移动一次,便有可能导致不能遍历完所有的情况。第一条边的循环变量为j,第二条边的循环遍量为i,第三条边的循环变量为j,第四条边的循环变量为i。遍历每一条边的时候,均遵守。##代码随想录day2。
2023-05-25 17:56:08
61
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人