- 博客(187)
- 收藏
- 关注
原创 场景设计:用OOP的思想设计一个生产者消费者的模型
说一些思路,这个问题首先可以使用阻塞队列来直接构建,因为本身就可以直接应用其生产者消费者模型来进行。然后就是一些搭建的思路!
2022-07-26 21:36:03
311
1
原创 恶补多线程编程实践4之ReentrantLock的使用以及condition
condition对象的await()\signal()\signalAll()必须在获得lock.lock()占用锁之后调用,而且最后必须手动释放锁。Condition的await()方法相当于Object的wait()方法,会释放锁;Condition的signal()方法相当于Object类的notify()方法,Condition类的signalAll()方法相当于Object的notifyAll()方法,会唤醒对应的await()线程。...
2022-07-26 16:19:00
359
原创 恶补多线程编程实践3之CyclicBarrier
将CountDownLatch的计数器初始化为newCountDownLatch(n),每当一个任务线程执行完毕,就将计数器减1countdownLatch.countDown(),当计数器的值变为0时,在CountDownLatch上await()的线程就会被唤醒。做法是初始化一个共享的CountDownLatch(1),将其计算器初始化为1,多个线程在开始执行任务前首先countdownlatch.await(),当主线程调用countDown()时,计数器变为0,多个线程同时被唤醒。...
2022-07-24 21:55:24
260
原创 恶补多线程编程实践2之CountDownLatch
将CountDownLatch的计数器初始化为newCountDownLatch(n),每当一个任务线程执行完毕,就将计数器减1countdownLatch.countDown(),当计数器的值变为0时,在CountDownLatch上await()的线程就会被唤醒。做法是初始化一个共享的CountDownLatch(1),将其计算器初始化为1,多个线程在开始执行任务前首先countdownlatch.await(),当主线程调用countDown()时,计数器变为0,多个线程同时被唤醒。...
2022-07-24 17:19:04
191
原创 恶补多线程编程实践1之信号量Semaphore
具体的原理其实也很简单,首先初始化一个信号量,并赋给它一个初始化的值,代表他初始化的时候有多少个令牌,然后每次线程在进行操作的时候,可以先进行令牌的获取,如果获取到就可以顺利执行,否则如果信号量中没有令牌了,就会进行阻塞线程。同时还有一个比较关键的操作是释放令牌,其实也就是往信号量里添加令牌。release()就是释放令牌,其实就是添加一个令牌,而acquire()是获取令牌,会减少一个令牌。应用一停车场场景,车位数量有限,同时只能容纳10台车,车位满了之后只有等里面的车离开停车场外面的车才可以进入。...
2022-07-24 15:32:42
129
原创 Java实现大数阶乘
对于大数而言,计算阶乘肯定是超过了int乃至是long所能表示的范围,因为得到的结果很大,所以必须要使用其他的方式来去实现阶乘的实现。主流的方式是使用数组,利用空间来换时间。具体的思路就是用一个数组,这个数组的长度一定大于最终你想要计算的大数的阶乘的长度,然后每次将数组中的数进行计算,并更新结果。......
2022-07-13 11:43:03
1498
原创 多余的边(判断有向图是否存在环)
多余的边其实就是判断是都有环出现,如果有环出现,就返回最后那条导致环的有向边。这里直接使用并查集即可初始时,每个节点都属于不同的连通分量。遍历每一条边,判断这条边连接的两个顶点是否属于相同的连通分量。不属于的话既可以进行合并,如果属于的话说明出现环,即可返回该有向边!......
2022-07-08 17:26:40
331
原创 恢复空格
恢复空格前缀树+动态规划,前缀树真的好用,复杂度可以降很多!!!定义dp[i] 表示考虑前 i个字符最少的未识别的字符数量,从前往后计算dp 值。
2022-07-06 21:09:46
157
原创 单词搜索 II
单词搜索 II比较好想到的做法就是DFS+回溯。需要注意的是将答案存在一个set中,可以有效地去重。上述的方式复杂度比较高,主要的问题出在:每次都需要对每个word进行比对。如果使用前缀树,就可以实现每次DFS的时候通过比对前缀树,即可比对全部所有的word。......
2022-07-05 22:18:14
139
原创 至少有 K 个重复字符的最长子串
至少有 K 个重复字符的最长子串可以进行分治,从大开始一步一步的缩小范围来得到最大的满足条件的最长子串。因为有些字符不满足总数大于k的要求,那么只要是包含该字符的子字符串肯定不行,因此可以按照这样的字符为界限进行分割,然后再进行满足的情况下的进一步判断。...
2022-07-04 11:04:49
443
原创 分割回文串
分割回文串经典的回溯做法:从字符串的起始位置开始进行遍历,如果当前子字符串可以成为回文串,那就往下找下去。之后回溯到当前并不选取这个回文串的时候,然后继续往下进行判断。
2022-06-28 20:16:52
217
原创 单词接龙(从单词 beginWord 和 endWord 的 转换序列)
单词接龙这里说一下BFS的思路吧,双向BFS解决这个问题会更快,有兴趣的自己去看吧。对于BFS的思路其实也很简单,首先选择将beginWord放到对列中,这就属于第一层,然后每次将这一层字符串取出来进行判断,同时将该层字符串的下一层元素全部放到对列中。...
2022-06-26 20:59:35
372
原创 平均拆分数组
问题一:给一个数组,输出这个数组拆分为两个数组,使得两个数组的差值最小问题二:给一个数组,是否可以等值分割成两个子集,使得两个子集的元素和相等。问题三:将一个数组拆分为两个数组使得两个数组的差值最小,求出对应的两个数组...
2022-06-23 21:33:59
594
原创 offer_II_109开密码锁
开密码锁其实这题和那个单词接龙都很像,做法就是使用BFS广度优先遍历.先将0000加入队列中,然后将0000能够转移的状态全部加入队列,作为下一步可能存在的所有状态,然后再将这一层的全部状态进行一一判断,之后将对应能够得到的转移的状态加入到下一步的队列中.进行判断即可.其他的就是一些细节,看代码的注释!...
2022-06-11 19:48:03
1522
原创 子序列的数目
子序列的数目使用动态规划:这里dp[i][j]表示字符串s的前i个子字符中字符串t的前j个子字符出现的个数.那么状态转移方程这样考虑:因此状态转移方程为:
2022-06-10 20:28:16
529
原创 最少回文分割
最少回文分割动态规划来做:首先之前说过可以使用动态规划来判断一个字符串s的所有子串是否是回文子串,动态规划判断回文子串这个的原理就是用dp[i][j]表示s[i…j] 是否为回文串,那么状态转移方程为:可以从尾部开始进行动态规划,这样的话可以将所有的子字符串全部判断完.有了上面的基础之后,可以先通过上面的动态规划得到每个子字符串的回文情况.那么新的动态规划就好想了,dp2[i]表示字符串的前缀 s[0…i]的最少分割次数....
2022-06-07 20:59:19
415
原创 offer_II_106二分图
二分图对于图中的任意两个节点 u 和 v,如果它们之间有一条边直接相连,那么 u 和 v 必须属于不同的集合。如果给定的无向图连通,那么我们就可以任选一个节点开始,给它染成红色。随后我们对整个图进行遍历,将该节点直接相连的所有节点染成绿色,表示这些节点不能与起始节点属于同一个集合。我们再将这些绿色节点直接相连的所有节点染成红色,以此类推,直到无向图中的每个节点均被染色。如果我们能够成功染色,那么红色和绿色的节点各属于一个集合,这个无向图就是一个二分图;如果我们未能成功染色,即在染色的过程中,某一时刻访问
2022-06-06 20:42:59
95
原创 [翻转字符]
翻转字符动态规划:方法一:其实最主要的是确定好状态,对于每个位置而言,就两种状态:针对每一个字符有两种选择,即翻转该字符和不翻转该字符.定义两个状态 f0(i - 1) 和 f1(i - 1),表示前 i 个字符翻转后得到的递增字符串分别以 ‘0’ 和 ‘1’ 结尾时共所需的最小翻转次数。那么状态的转移方程即为:方法二:dp表示翻转的最小代价,count表示1出现的个数.那么每次只需要判断:当出现0的时候,是将前面的1全部翻转,还是按照最小翻转代价dp的情况下将这一位的0也翻转为1.即dp =
2022-06-05 14:49:56
216
原创 分割回文子字符串
分割回文子字符串首先使用动态规划得到所有子串是否是回文子串的情况,这里参考这个动态规划判断回文子串,然后思路就是DFS+回溯即可.先判断当前子串是否是回文子串,如果是就DFS继续往后进行,然后回溯找到所有的情况即可!
2022-06-02 16:16:59
215
原创 动态规划判断回文子串
这里给出一个通过动态规划的方式对一个字符串s的所有子串进行是否是回文子串的判断,时间复杂度超级低.具体的思路是:dp[i][j]表示s[i…j] 是否为回文串,那么状态转移方程为:所以,从尾部开始将所有子串进行遍历然后即可获取每个子串的判断.
2022-06-02 16:13:09
300
原创 外星文字典
外星文字典这题其实还是拓扑排序的问题,拓扑排序问题就是解决有向图是否有环的.如果没有环则就是拓扑排序,否则就不是拓扑排序.同样,做这类题的思路就是:这道题里需要将外星文字典中的每个字母看成一个节点,将字母之间的顺序关系看成有向边。对于外星文字典中的两个相邻单词,同时从左到右遍历,当遇到第一个不相同的字母时,该位置的两个字母之间即存在顺序关系。以下两种情况不存在合法字母顺序:其余情况下都存在合法字母顺序,可以使用拓扑排序得到字典顺序。
2022-05-31 21:32:34
255
原创 删除无效的括号
删除无效的括号给你一个由若干括号和字母组成的字符串 s ,删除最小数量的无效括号,使得输入的字符串有效。返回所有可能的结果。答案可以按 任意顺序 返回。示例 1:输入:s = “()())()”输出:[“(())()”,“()()()”]示例 2:输入:s = “(a)())()”输出:[“(a())()”,“(a)()()”]题目让删除括号使得剩下的括号匹配,要求删除最少的括号数,并且要求得到所有的结果。可以使用回溯算法,尝试遍历所有可能的去掉非法括号的方案。首先利用括号匹配的
2022-05-30 22:57:56
267
原创 课程表(拓扑排序问题)
课程表你这个学期必须选修 numCourses 门课程,记为 0 到 numCourses - 1 。在选修某些课程之前需要一些先修课程。 先修课程按数组 prerequisites 给出,其中 prerequisites[i] = [ai, bi] ,表示如果要学习课程 ai 则 必须 先学习课程 bi 。例如,先修课程对 [0, 1] 表示:想要学习课程 0 ,你需要先完成课程 1 。请你判断是否可能完成所有课程的学习?如果可以,返回 true ;否则,返回 false 。示例 1:输入
2022-05-30 21:34:32
528
原创 不同的二叉搜索树
不同的二叉搜索树给你一个整数 n ,求恰由 n 个节点组成且节点值从 1 到 n 互不相同的 二叉搜索树 有多少种?返回满足题意的二叉搜索树的种数。示例 1:输入:n = 3输出:5示例 2:输入:n = 1输出:1*使用动态规划解决,dp[i]表示i个节点能够构建为二叉搜索树的数量.因为可以将这个问题分解成若干个子问题来解决.对于n而言,每个位置都可以做为根节点,而在这种情况下,例如当前作为根节点的是i,那么dp[i]问题可以分解为左右两个两个子树的数量求解问题.对于0<j&l
2022-05-29 22:55:24
78
原创 冗余连接(并查集问题)
冗余连接树可以看成是一个连通且 无环 的 无向 图。给定往一棵 n 个节点 (节点值 1~n) 的树中添加一条边后的图。添加的边的两个顶点包含在 1 到 n 中间,且这条附加的边不属于树中已存在的边。图的信息记录于长度为 n 的二维数组 edges ,edges[i] = [ai, bi] 表示图中在 ai 和 bi 之间存在一条边。请找出一条可以删去的边,删除后可使得剩余部分是一个有着 n 个节点的树。如果有多个答案,则返回数组 edges 中最后出现的边使用并查集即可,官方给的解答已经很棒了
2022-05-29 22:49:27
178
原创 单词拆分.
单词拆分给你一个字符串 s 和一个字符串列表 wordDict 作为字典。请你判断是否可以利用字典中出现的单词拼接出 s 。注意:不要求字典中出现的单词全部都使用,并且字典中的单词可以重复使用。示例 1:输入: s = “leetcode”, wordDict = [“leet”, “code”]输出: true解释: 返回 true 因为 “leetcode” 可以由 “leet” 和 “code” 拼接成。使用动态规划,dp[i]表示字符串s的长度为i是能不能成功被拼接.因此只需要保证
2022-05-29 22:46:36
76
原创 并查集的问题
关于并查集的问题来源于左神算法视频中.是一个并查集的模板,最重要解决的问题是:支持集合的合并.其中最核心的两个功能是:1.查询两个样本是否属于一个集合2.合并两个集合具体的思路全部写在了代码的注释中.public class Union { //对样本进行包装 为元素 public static class Element<V> { public V value; public Element(V value) {
2022-05-27 16:10:43
118
原创 为高尔夫比赛砍树
为高尔夫比赛砍树你被请来给一个要举办高尔夫比赛的树林砍树。树林由一个 m x n 的矩阵表示, 在这个矩阵中:0 表示障碍,无法触碰1 表示地面,可以行走比 1 大的数 表示有树的单元格,可以行走,数值表示树的高度每一步,你都可以向上、下、左、右四个方向之一移动一个单位,如果你站的地方有一棵树,那么你可以决定是否要砍倒它。你需要按照树的高度从低向高砍掉所有的树,每砍过一颗树,该单元格的值变为 1(即变为地面)。你将从 (0, 0) 点开始工作,返回你砍完所有树需要走的最小步数。 如果你无法砍
2022-05-23 22:48:44
155
原创 关于丑数(只包含质因子 2、3 和 5 的数称作丑数,求按从小到大的顺序的第 n 个丑数。)
丑数我们把只包含质因子 2、3 和 5 的数称作丑数(Ugly Number)。求按从小到大的顺序的第 n 个丑数。示例:输入: n = 10输出: 12解释: 1, 2, 3, 4, 5, 6, 8, 9, 10, 12 是前 10 个丑数。这道题真的必须要好好研究一下了,我们得到的丑数一定是之前的丑数的 2、3 、5倍,并且当前位置要得到丑数只是取其中最小的那个.因此我们定义三个指针p2、p3、p5分别代表当前2、3 、5这些系数所叠加的丑数的索引位置index,也就是说当前该系数所得
2022-05-19 22:21:57
435
原创 最小K个数
最小K个数设计一个算法,找出数组中最小的k个数。以任意顺序返回这k个数均可。示例:输入: arr = [1,3,5,7,2,4,6,8], k = 4输出: [1,2,3,4]其实就是一道排序题的变形,方法很多!你可以使用无脑的直接调用api排序后取出前k个的方式. public static int[] smallestK_1(int[] arr, int k) { Arrays.sort(arr); int[] ans = new int[k];
2022-05-19 15:35:28
144
原创 最长单词]
最长单词给定一组单词words,编写一个程序,找出其中的最长单词,且该单词由这组单词中的其他单词组合而成。若有多个长度相同的结果,返回其中字典序最小的一项,若没有符合要求的单词则返回空字符串。示例:输入: [“cat”,“banana”,“dog”,“nana”,“walk”,“walker”,“dogwalker”]输出: “dogwalker”解释: "dogwalker"可由"dog"和"walker"组成。字典树+回溯:构建一颗字典树,先将所有的单词都放在字典树中.接着排序,然后将
2022-05-19 11:43:23
367
原创 [模式匹配]
模式匹配你有两个字符串,即pattern和value。 pattern字符串由字母"a"和"b"组成,用于描述字符串中的模式。例如,字符串"catcatgocatgo"匹配模式"aabab"(其中"cat"是"a",“go"是"b”),该字符串也匹配像"a"、"ab"和"b"这样的模式。但需注意"a"和"b"不能同时表示相同的字符串。编写一个方法判断value字符串是否匹配pattern字符串。public static boolean patternMatching(String pattern,
2022-05-19 10:44:00
90
原创 字母与数字
字母与数字给定一个放有字母和数字的数组,找到最长的子数组,且包含的字母和数字的个数相同。返回该子数组,若存在多个最长子数组,返回左端点下标值最小的子数组。若不存在这样的数组,返回一个空数组。示例 1:输入: [“A”,“1”,“B”,“C”,“D”,“2”,“3”,“4”,“E”,“5”,“F”,“G”,“6”,“7”,“H”,“I”,“J”,“K”,“L”,“M”]输出: [“A”,“1”,“B”,“C”,“D”,“2”,“3”,“4”,“E”,“5”,“F”,“G”,“6”,“7”]示例
2022-05-17 23:20:03
247
原创 数对和[设计一个算法,找出数组中两数之和为指定值的所有整数对。一个数只能属于一个数对。]
数对和设计一个算法,找出数组中两数之和为指定值的所有整数对。一个数只能属于一个数对。示例 1:输入: nums = [5,6,5], target = 11输出: [[5,6]]示例 2:输入: nums = [5,6,5,6], target = 11输出: [[5,6],[5,6]]其实就是两数之和的变形,两数之和中使用了时间复杂度为O(n)的做法,其实就是放在Map中,然后每次判断一下target-num在不在map中,如果在直接去除即可.所以第一种做法就是这个. public
2022-05-17 21:29:26
458
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人