- 博客(48)
- 问答 (1)
- 收藏
- 关注
原创 Java枚举类学习
java5后引入,其实看以下代码就很能入门了。定义任务状态,以及状态流转。别的都知道,主要居然有values()表示所有类型,还有ordinal表示下标。
2025-01-17 14:14:05
179
原创 Word自定义配置
1.修改恢复键入(取消撤销)快捷键从Ctrl+y到ctrl+shift+z(为了与IDEA保持一致)先关闭搜狗输入法的Ctrl+shift+z,再修改word的自定义快捷键。
2025-01-10 11:43:28
221
转载 MarsCode奇妙货币交易问题——数学
另外,可能有数学家已经证明V= (V-2)的情形,即此时的。那么就可以利用数学的取模mod 和除法 /,来迭代判断每次。>= V-2,这种情况不满足[-2,2]了,但是可以变成。这篇文章有答案,代码很简洁,但蛮难理解的。都必须满足[-2,2]之间。都满足,就说明YES。
2025-01-02 01:24:25
56
原创 MarsCode非重叠子数组的最大和——滑动窗口
这样实现比先求出f2Left[i]表示i左边n2长子数组最大和,f2Right[i+n1]表示i+n1右边n2长最大子数组和,然后 滑动窗口迭代维护n1长的子数组的和,比较加上左边界f2Left或右边界f2Right谁更大的方法更优,因为边界情况能简化一些。然后一次遍历,left从0遍历到n-subArrN,同时记录更新最大值。具体实现上,可以先动态规划求出f1[i]表示左边界下标<= i 的n1长的子数组的最大和,以及f2[i + n1]求出左边界>= i + n1的n2长的子数组的最大和。
2025-01-01 03:16:09
308
转载 lc1378使用唯一标识码替换员工ID——left join
外连接有三种,左外连接(LEFT OUTER JOIN)、右外连接(RIGHT OUTER JOIN)和全外连接(FULL OUTER JOIN)。outer一般可以省略。以左外连接为例,是以左表为主表,主表所有的行都要显示,即使连表没有对应的项或者说不匹配,也要显示null。本身不难,注意格式规范。每个关键字开头顶行。注意为null的也要显示出来。只显示满足连接条件的项。也可以全省略from a,b on...还有区别内连接和外连接。
2024-12-29 21:25:16
33
原创 Marscode连续子串和的整除问题——前缀和+哈希表
(preSum[j] - preSum[i-1]) % b == 0,等价于 preSum[j] % b == preSum[i-1] % b。任意连续子数组subArr[i..j] = preSum[j] - preSum[i-1] 前缀和之差。那么subArr%b == 0即等价于。那么在遍历求前缀和时,就一边更新前缀和,一边哈希记录已有的前缀和%b的数量,一边ans+=数量。注意初始化map 有0,1键值对。,咋还是没有第一时间想到哎。方法:前缀和+哈希表。
2024-12-29 17:37:02
155
原创 Marscode小M的星球时代冒险——灵活bfs或dfs
最开始想的是回溯,但不是,应该用bfs。从做题角度,一般m*n矩阵不是bfs就是dfs或者二维动态规划。难点在于它不是简单的岛屿问题,或者最短路径什么的。难点在于每次向四个方向移动时,以前遍历过的位置还要遍历吗,应该要才行,因为不确定这个路径到遍历过的位置会不会跨越次数更少,但这样不会导致死循环吗,比如绕着个正方形一直死循环遍历。所以要很灵活的定义为,未遍历过或者跨越次数更少才允许往这个方向移动。ERROR: 坑还多,传递的array的索引是从1开始的,还要减1处理。
2024-12-29 02:22:32
218
原创 lc240.搜索二维矩阵II——右上角点(技巧)
非常充分地利用了,行和列分别递增的性质。最开始想的太简单了,自动脑补了每一列的最小值都大于前一列的最大值,但题意不是的,所以不能先选择第一行二分,再选择列二分做,得遍历每一列二分查找。若 < target 说明,target肯定不在它这一行,因为该点就是这一行最大值了,可以x++;若 > target 说明,target肯定不在这一列,因为该点就是这一列最小值了,可以y--;初始比较点(x,y)选择右上角(0,n-1),然后从这个点开始判断,若==target返回;
2024-12-20 23:28:15
129
原创 lc两两交换链表中的节点——链表题哑结点技巧
使用哑结点,就不用顾虑第一对要更新head的情况,直接返回dummyNode.next并且,每次迭代思想为交换当前节点的下两个节点(相当于当前节点时preNode)。不用哑结点技巧比较烦。
2024-12-16 17:59:12
200
原创 lc42接雨水——双指针
朴素些,先求第0行的能填的水,再求第1行,第2行...求某一行(第i行)填的水,O(n)时间复杂度,双指针找到第一个值>i的作为左边界,再找下一个值>i的下标作为右边界,每次加right-left-1,再left = right找下一个双界。在法2思想的基础上,时间复杂度为什么高,就是因为每一列都要去求左边和右边的最高值,其实会重复计算很多,用动态规划进行优化,先迭代求出每一列的左边最高值和右边最高值dp[]数组,那么计算每一列能接的水就能优化为O(1)了,总时间复杂度就为O(n)了。
2024-12-15 21:34:49
686
原创 lc54螺旋矩阵——模拟
就兜圈,先外层,再内层,每一圈,先上->右->下->左,要计算多少圈,观察规律就是行和列中更小的那个的二分之一,注意额外讨论下最后一圈只有一个或者只有一行或者只有一列这种特殊情况。
2024-12-14 21:40:38
190
原创 lc146LRU缓存——模仿LinkedHashMap
要实现O(1)的get和put,那得用哈希表但手撸一个哈希难度太大,应该不至于考那么过分,那就基于使用现有map的前提下实现LRU缓存。关键是要记录最近最少使用的是哪一个,那么需要每次将最新使用的放到“最前面”,这样每次取“最后的”那个就是最近最少使用的。单向链表的话需要知道被移动元素的前一个元素才方便移动,所以最后相比之下双向链表最合适。调用java现有的LinkedHashMap的方法,但不太理解反正都不需要扩容,super(capacity, 1F, true);不行吗,干嘛还弄个装载因子0.75。
2024-12-13 20:55:40
633
原创 lc128最长连续序列
比如 0,1,2,3,4这种数组,会重复计算很多次,0计算出长度5了,遍历1时又计算出长度4,但其实计算0开始的长度时,1的长度已经算过了,没必要再重复计算了。所以优化为,遍历元素x以x为起始计算长度前,先判断x-1存不存在于set(或者说数组)中,存在则没必要计算这个了,当计算x-1时就会计算它了。官解做法为,一次遍历将所有元素存入set,然后再遍历每个元素x,看x+1,x+2...是否存在于set中,这样遍历更新记录最长长度。但nlogn,题目要求O(n)时间复杂度,提示我用哈希表我也想不到...
2024-12-12 16:26:06
255
原创 lc78子集——回溯或二进制枚举(迭代)
种可能,对于子集是否选择每个元素正好可以用一个bit表示,那么子集的情况,可以用 0(00...0 , n个0) ,1(00...0001), ...,-1( 11...1,n个1)这些二进制数表示是否选择某个元素。然后判断某个具体元素是否被选择,就通过移位 与 &运算来判断。这道题,也可以通过迭代,不用递归完成。差不多,也是用回溯优化遍历,甚至更简单。
2024-12-11 15:17:57
147
原创 lc169多数元素——投票技巧
若要求必须空间复杂度为O(1),投票法。设数组每个元素都有权值,是众数则表示权值1,非众数则表示-1,那么因为众数> n/2,所以整体数组总权值 > 0。并且当从左往右遍历数组时,若遍历到某个数时的现有总权值为0,说明剩下后面的还未遍历数组的总权值>0,且它的众数就是整个数组的众数。这个前提必须是众数数量大于总数的一半,怎么严谨证明不会,但可以凭感觉,即使前面部分数组总权值为0时的“伪众数”不是真正的那个众数,但最后能让总权值>0的众数一定是那个真众数。法1:用哈希表辅助记录。
2024-12-11 14:49:49
232
原创 lc字符串相加——模拟
不准调用封装好的那些库。手动模拟两数相加,记录进位。主要当其中短的数字计算完了怎么办,技巧为下标为负数时就当做0,相当于补0一样。
2024-12-10 23:32:37
270
原创 lc46全排列——回溯
(1*n*n-1*...*2)次,但因为每次要拷贝新的list和set(list和set加起来共n个元素),所以每次调用bruteForce前拷贝都需要O(n),所以算上拷贝时间复杂度公式应该为。官解十分巧妙利用了list的未排列部分来作set,这样可以每次选择list的未排列部分作为下一个排列的 来替代 从set中选择下一个排列的,然后通过回溯复原。为了快,选择set,每选了一个,set里就删除一个,再继续从里面随机选。可以不拷贝list,而是先添加,遍历完这次排列后,再删除,再开始下一个。
2024-12-10 19:43:24
398
原创 lc560合为k的子数组——前缀和+哈希表
第一次做真想不到啊...子数组和subArr[i-j] = preSum[j] - preSum[i-1],preSum[i]表示前缀和,即0-i下标的所有元素之和。那么求子数组和=k,可转化为。从subArr[0],[01]...[0-n-1][1][12]...[n-2_n-1]去暴力枚举所有子数组的可能,看是否和为k,一次遍历O(n)即可实现。preSum[j] - preSum[i-1] = k,即 preSum[i-1] = preSum[j] - k。法2:前缀和+哈希表。
2024-12-10 03:06:04
174
原创 lc438找到字符串中所有字母异位词——滑动窗口
法2主要每次比较窗口和s2是否为异位词需要遍历int[26],每次都需要*26,如果能优化为O(1)就好了。也是取s1的m长子串,但每次s1的m长子串和s2判断是否为异位词,采用int[26]数组(记录26个字母出现次数)比较是否相等。O((n-m)*mlogm),取s1的m长子串,排序后,每次和s2比较是否相等。O((n-m) * 26 + m),要先遍历s2求出s2的int[26]数组。但每次滑动都是+1,+1的滑动,还是偏暴力,不能一次性多滑动几步。法2:int[26]数组判断。
2024-12-08 16:43:03
187
原创 lc3无重复字符的最长子串——滑动窗口
哈希表主要方便记录滑动窗口有哪些元素,更新窗口时,把上次之前的给删了。结合2种情况,left = Math.max(left, map.get(cstr[right])+1);比如abcc,abca,c滑动到第一个,a滑动到bca为窗口。2.重复元素已经不在left-right表示的滑动窗口之间了,而是left之前出现过罢了,那left不变。比如 abcca 的情况,遇到第2个a时,left 仍 = 3,而非=map.get(ch) + 1。不用删除上次重复的及之前的元素的哈希项,而是直接更新left,
2024-12-08 15:36:28
144
原创 lc49字母异位词分组——HashMap记录
20.25-字母异位词就是相同字母单词不同排序,那就想办法设计一种哈希,将不同单词但相同字母异位词映射到同一个哈希值,HashMap的key。
2024-12-07 21:02:18
175
原创 lc73矩阵置零——尽可能减少空间复杂度
常量空间,第一次做不太好想到。法1是用额外数组记录行列的0情况,法2优化为 用原矩阵的,第一列记录每行有0的情况,第一行用于记录每列有0的情况。而对于第一行和第一列本身就有0的情况,额外拿2个变量(常量)记录,有的话,把其置位0.当然也可进一步优化,只用一个m[0][0]标记第1行有无0,再额外用一个变量记录第一列有无0即可。很容易想到,O(m+n)空间复杂度,记录哪些行,哪些列有0。注意第二次遍历,从1,1开始,要忽略第一行和第一列。
2024-12-07 20:23:04
341
原创 lc268丢失的数字——数学和巧妙异或
第一次想,比较容易想到,先求0-n这n+1个数之和sum,再遍历数组用sum去减去每一个元素,但这样涉及乘法,说不定以后测试用例很大时,会溢出,且大数乘法比较慢吧。另外可以用异或的方法,两个相同的数异或后为0,那么可以异或这0-n这n+1个数,并且再遍历数组异或每个元素,这样就能求出只异或了1次的那个数。
2024-12-05 16:23:51
110
原创 lc461. 汉明距离——异或+统计二进制1个数
统计两个数的二进制不同位的个数,首先就应该想到异或才对,再统计1个数。统计1个数用移位与1与运算应该最高效。
2024-12-04 15:20:12
163
原创 lc384打乱数组——怎么随机打乱一个数组?
怎么随机打乱一个数组呢?最常规的应该想到是,先n个数随机生成一个下标取出作为随机数组的第一个,然后移除这个数,后面的补上去,再n-1里面随机生成下一个下标,以此类推。可以在同一数组上随机打乱,随机生成一个下标后直接和最后一个交换,相当于最先抽到的放数组最右边,再依次往左边放,这样时间复杂度只有O(n),每生成一个只用swap交换一次,不用移动。,因为要移除那个数,然后再把后面的移过去补位。
2024-11-30 15:15:57
220
原创 lc70爬楼梯——经典动态规划
动态规划,自底向上计算,且记忆化。动态规划最重要的就是找到递推表达式,这里为。没学动态规划前,使用递归,超时,因为重复计算太多,还容易栈溢出。只需记录前两个的值,所以其实不用数组都行。
2024-11-29 20:50:26
142
原创 lc278第一个错误的版本——二分
一眼二分,不过要改造下二分,方法蛮多的,这里用找到了true把mid当right往前找是否有更小版本,最后left = right时,就是最小版本号了。有坑,不能mid = (left + right)/2,有测试用例会int溢出。
2024-11-28 16:42:52
114
原创 lc88合并两个有序数组——归并排序或巧妙逆向双指针
若第一个数组大小就够容纳m+n个元素,那么可以巧妙使用逆向双指针,常规指针从小向大增长,每次选两个指针指向更小的那个填进,但这样若arr2更小会把arr1的覆盖导致只能先另用个空数组存。但若逆序反过来,从大往小递减比较,大的填进arr1的后边部分,就不会有覆盖问题,就可以不用额外数组空间了。最容易想到就是常规双指针,但需要另外新增一个数组先存放。法1:就相当于归并排序的合并操作。
2024-11-28 16:19:35
357
原创 lc108有序数组化为平衡二叉搜索树——分治递归或手撸AVL树
分治思想,利用平衡BST的中序遍历即升序得出 中间值为分割,中间值作root,前面的作left,后面的作right。
2024-11-27 16:58:15
150
原创 豆包红包运气排行榜——灵活模拟
key为name,value为money以及抢到money的时间戳,方便记录谁先第一个达到相同金额。error:treemap只能通过key比较对key进行排序,不能通过value对key进行排序。官方用例的意思,不是按谁先达到金额数,而是相同金额数的看谁先第一个抢红包。用了时间戳反而出错,逆天。那就换成用hashmap,先统计每个人的总金额,再化为list进行sort比较,最后输出结果。原本以为很简单,没想到一个人可以重复抢多次,记录累加进行排名。放弃时间戳,直接按原始出现顺序。
2024-11-27 16:38:51
234
原创 lc101对称二叉树——递归或层序遍历
本来想的是,层序遍历,每层获取总数,然后像判断回文串一样,前后双指针比较,不相等则false,看了官解,发现也可以巧妙改变加入队列(双向链表的)的节点顺序,类似递归的思路,放左左,右右,再放左右,右左,然后每次2个2个成对取出判断。
2024-11-26 20:48:23
155
原创 lc236二叉树最近公共祖先
具体记录方式,法1.1用后序遍历的方式记录祖先if (!// 树就没有p或q节点// 查找最后一个相同的祖先elsebreak;// 后续遍历的方式记录公共祖先// list模拟栈while (!= null) {= null) {// 若找到p了返回= pre) {} else {list.pop();pre = root;// 最后都没找到,没有该节点法1.2遍历时,用hashtable记录每个子节点的父节点。
2024-11-25 16:42:10
224
空空如也
巨佬们帮我看看多个三目运算符嵌套怎么分析的,应该怎么改?
2021-11-22
TA创建的收藏夹 TA关注的收藏夹
TA关注的人