- 博客(40)
- 收藏
- 关注
原创 Day35-代码随想录-分发饼干455+摆动序列376+买卖股票的最佳时机II122
一定要理清题意:刚开始我还以为一块饼干可以分成好几小份,给不同胃口的孩子们吃。后面才发现是自己理解错题意了,那肯定是一块饼干就给一个小孩吃。思路就是:将尺寸大的饼干先给胃口大的孩子吃,如果给胃口小的孩子吃了,那这块饼干不就浪费了嘛,通过这样能发现这样找局部最优,最后能找到全局最优,无法提供反例,所以这是一道贪心算法类的题。直接将最终利润拆分为每次的利润,然后只收集每天的正利润就可以得到最大利润了。
2025-04-02 17:11:15
152
原创 Day34-代码随想录-组合77+组合总和III216+分割回文串131+子集78+全排列46+N皇后51
看了题解之后,自己独立写的时候,出错的地方以后复习的时候需要注意一下:①在初始化棋盘的时候,Arrays.fill是java内置方法,可以将c这个一维数组里面的所有元素直接填充为'.',比双重循环更为便捷,只需一行代码即可实现;这算是一道标准的模板题,都是将问题抽象为树形结构,不过子集问题与组合问题、分割问题的区别就是子集是收集树形结构中树的所有节点的结果,而后两者则是收集树形结构中叶子结点的结果。组合思路:回溯法的搜索过程就是一个树型结构的遍历过程,用for循环用来横向遍历,递归的过程是纵向遍历;
2025-04-01 13:20:30
510
原创 Day33-代码随想录-二叉搜索树中的众数501
思路:充分利用二叉搜索树的有序的特点,采用中序遍历,并同时利用前一个节点pre和当前节点root进行比较,由于搜索树的特性,这个众数也只会出现在pre和root上。在遍历的时候,还需要构建一个当前count和最大count-maxCount,以便实时更新最大频次,同时更新结果数组(如果当前的count大于之前的最大count-maxCount,需要将之前结果数组全部清空,然后存放最新的频次最高的节点元素)。
2025-03-30 17:55:07
128
原创 Day32-代码随想录-验证二叉搜索树98+二叉搜索树的最小绝对差530
一看题目很简单,但很容易出错,很容易陷入误区。刚开始,我是直接用root.left.val < root.val && root.right.val > root.val来判断了,结果报错,还百思不得其解,后来发现是自己没有真正领悟到二叉搜索树是什么。所以遇到空节点了应该返回true。在写单层递归逻辑的时候,需要不断判断和更新max_val和root_val的值。节点10大于左节点5,小于右节点15,但右子树里出现了一个6 这就不符合了。所以以上代码的判断逻辑是错误的。还有很重要的一点是,
2025-03-29 16:55:26
305
原创 Day31-代码随想录-最大二叉树654+合并二叉树617+二叉搜索树中的搜索700
刚开始还在疑惑怎么返回子树,还说确定了节点之后要不要再遍历它的子树,完全没必要,这是自己没掌握好二叉树的结构。只要匹配到与目标值相等的节点,直接返回即可,因为他返回的是TreeNode结构,又不是数值int。思路:这个跟构造二叉树是差不多的,只不过需要每次递归需要找到数组的最大值,然后根据最大值对数组进行左右分割,遵循左闭右开的准则。
2025-03-28 20:31:54
194
原创 Day30-代码随想录-路径总和112+路径总和ii113+从中序与后序遍历序列构造二叉树106
这里要判断路径和是否与目标值相等,直接将目标值作为计数器,每遍历一个节点,就将其值减去,最后判断到达叶子节点时目标值是否已经为0,如果为0,说明该条路径和已经达到目标值了,如果不为0,则继续寻找下一条路径。从前序与中序遍历序列构造二叉树与上面这道题是一模一样的思路,代码完全一样,不在赘述。思路:主要难在每次从后序数组确认中节点后如何进行左右子树的分割并递归(重要!这个相当于求所有路径和路径和两道题的结合版。
2025-03-27 17:37:20
303
原创 Day29-代码随想录-左叶子之和404+找树左下角的值513
思路:求的是左叶子之和,不是最左侧叶子节点的和,所以即使是右子树,里面也会包含左叶子。使用递归的话,一定要明确递归三要素,这里递归的终止条件仍然是null时返回0(因为到空节点时,它的左叶子一定是0)。这里还需要明确的是如何判断是左叶子:通过它的父节点和它的左右孩子共同决定-如果它是父节点的左孩子,同时它的左右孩子都为空,那就说明他一定是左叶子。单层递归的逻辑:当遇到左叶子节点的时候,记录数值,然后通过递归求取左子树左叶子之和,和 右子树左叶子之和,相加便是整个树的左叶子之和。
2025-03-26 20:10:00
195
原创 Day28-代码随想录-平衡二叉树110+二叉树的所有路径257
平衡二叉树的定义是左右子树的高度差不能大于1。看到这种类型的题,一般会想到用递归的方法来做,一旦用递归,就需要明确递归的三部曲。(2)递归终止条件:对于二叉树来说,一般递归的终止条件都是当前节点为空,返回0;(3)单层递归的逻辑:需要判断左右子树的高度差,如果已经大于1,说明不是平衡二叉树,直接返回-1;递归与回溯是相伴相生的,递归遍历的过程中,一旦遇到叶子结点,就要回溯,不然无法回到其他路径分叉点。在这里,递归的终止条件就不像之前那样遇到空节点返回0,这里是遇到叶子节点后对其进行处理(收获结果的过程)
2025-03-25 17:04:00
276
原创 Day27-代码随想录-二叉树的最大/最小深度(递归法)+N叉树的最大深度559+完全二叉树的节点个数222
本题可以使用前序(中左右),也可以使用后序遍历(左右中),使用前序求的就是深度,使用后序求的是高度。的最长简单路径边的条数或者节点数(取决于深度从0开始还是从1开始)的最长简单路径边的条数或者节点数(取决于高度从0开始还是从1开始),所以本题中我们通过后序求的根节点高度来求的二叉树最大深度。这里用其他方法来做,同时需要搞清楚。
2025-03-24 17:47:56
191
原创 Day26-代码随想录-翻转二叉树226+对称二叉树101
使用递归法比较容易理解,检查是否轴对称就是看两边的子树是否对称(即最外侧节点是否相等,最内侧节点是否相等)。使用递归就按照递归三要素:确定递归函数的输入参数和返回值;这道题有很多方法,大致步骤就是在遍历时将左右孩子交换即可。
2025-03-23 13:11:07
135
原创 Day25-代码随想录-填充每个节点的下一个右侧节点指针116+117+二叉树的最大深度104+二叉树的最小深度111
这道题即使依然是层序遍历的模板题,但我还是没有一下子反应过来要怎么做,能想到某个节点的左孩子指向右孩子,但不知道不同节点的右孩子怎么指向左孩子,而且最右侧的节点的指针是不用管的,它初始化就已经填充了。跟上一道题一样,只不过不再是完美二叉树。逻辑是一样的,但代码稍微有点不同。
2025-03-22 17:19:51
197
原创 Day24-代码随想录-二叉树的右视图199+二叉树的层平均值637+N叉树的层序遍历429+在每个树行中找最大值515
模板同之前的层序排列,只不过需要在每层元素遍历的时候找最大值,这时候一般会定义一个初始max变量,一般是初始化为Integer.MIN_VALUE,然后再调用Math.max()方法。思路还是按照层序遍历的模板,不同点在于将当前结点的孩子入队的方式不同了,不再是判断左右孩子,而是将他的孩子作为一个整体的List,用for循环去遍历进行判断和入队。注意List和sum的数据类型都要变为Double。思路很简单,只要会了二叉树的层序遍历,这道题就迎刃而解,只需要判断是否到每层的最后面的元素即可。
2025-03-21 14:40:05
153
原创 Day23-代码随想录-二叉树的统一迭代遍历+二叉树的层序遍历102+二叉树的层序遍历II107
3.3 如果栈顶元素不是空指针,则先将该node弹出,避免重复操作;下面再将右左中节点添加到栈中(前序遍历-中左右,入栈顺序右左中)3.6 最后再将该node重新压入栈中并加上空指针(因为中节点已经访问过,但还没处理)3.4 再将右孩子压入栈中(添加右节点,空节点不入栈);3.5 再将左孩子压入栈中(添加左节点,空节点不入栈);4. 遇到空指针说明需要进行处理,将其放入数组中。层序遍历需要辅助一个数据结构即队列来实现,4.3 将该节点的值加进数组。1.定义一个栈访问和遍历树。2.首先将根节点压入栈中;
2025-03-20 17:06:32
248
原创 Day22-代码随想录-二叉树前中后序遍历递归+迭代144-94-145
思路:使用栈来访问和使用每一个结点,先将中间结点压入栈中,然后取出中间结点的值给数组,再判断该节点下有无左右孩子,有的话,是先将右孩子给压入栈,再将左孩子压入栈,(因为访问顺序是中左右,如果先将左压入栈的话就不是左先出了)。思路跟前序遍历类似,只不过要改变一下压栈的顺序,之前是中右左(出栈顺序为中左右),现在应该是中左右(出栈顺序是中右左)。他不同于前序和后序遍历,因为中序遍历是左中右,它的访问(遍历节点)和处理(将元素放进result数组中)无法做到同步,我们使用。
2025-03-19 17:21:54
183
原创 Day21-代码随想录-前K个高频元素347
这里有个问题是,是用大顶堆(从大到小)还是小顶堆(从小到大)的问题,一看题意输出前K个高频元素,肯定认为是大顶堆哇,但是因为我们只维护K个元素的有限队列,一旦添加元素大于K,如果这个元素大于队头,那岂不是要把队头给抛出去,但明明队头可能还要用,所以这时候用小顶堆会更合适,他抛出去的肯定是低频次的。
2025-03-18 16:14:44
225
原创 Day20-代码随想录-逆波兰表达式求值150+滑动窗口最大值239
这道题不难,能一下子想到使用栈去操作,自己主要的纠结点在怎么把字符串的运算符提取为真的运算符,我这死脑筋,题目已经明确说明了有效的算符为+-*/,我还在思考要是用判断语句无法判断完所有的运算符(比如什么逻辑运算符等),所以其实直接用if-else来匹配即可,注意这里的"+"是字符串,不能用==来判断,得用"+".equals(s)来判断。注意:deque是stack和queue默认的底层实现容器,deque是可以两边扩展的,而且deque里元素并不是严格的连续分布的。那么这个维护元素单调递减的队列就叫做。
2025-03-17 17:12:02
147
原创 Day19-代码随想录-有效的括号20+删除字符串中的所有相邻重复字符1047
这里引入了能够直接装字符串的栈,无需像平常的栈那样最后还要转为字符串,这个思路比较简单:一看重复且相邻,就马上想到用栈来做,当入栈元素与栈顶元素相同时,直接移除栈顶原酸,否则添加新元素。用栈的思想来做的话,就是先将左括号存入栈中,看遇到的右括号是否与之匹配(一定是从栈顶移除),如果所有的左括号都匹配完成了,栈内还有元素的话就说明存在上面三种情况之一。由于没有系统性的学过数据结构,所以看到这种简单的括号匹配问题是很难想到直接用栈结构来做的,所以还是需要学习一下,趁着现在时间还算充裕。
2025-03-16 14:46:41
188
原创 Day18-代码随想录-用栈实现队列232+用队列实现栈225
这两道都比较简单,但因为平常不怎么用到栈和队列,所以对他们的基本操作和知识还不太熟悉,需要后面加强,这个应该是个重点。栈和队列不是容器,它们反而相当于容器适配器。
2025-03-15 22:21:19
154
原创 Day16-代码随想录-找出字符串中第一个匹配项的下标28
为什么需要这个前缀表呢,我是这样理解的:对模式串中每i个字符之前的字符串中不是已经算出来不匹配的话需要回退到哪里吗,因为一旦后面的字符不匹配,由于有相同的前缀和后缀,舍弃掉前面的前缀,就可以拿后缀(这个后缀与前面的前缀是相同的)当做下一次的前缀(相当于记录之前已经匹配过的)最长相等前后缀就是前缀和后缀中相同且长度最长的那个子串的长度。这个最长公共前后缀会在KMP算法中发挥重要作用,里面有个next数组,实际上他就是一个前缀表,用来回退的,它记录了模式串与文本串不匹配的时候,模式串应该从哪里开始重新匹配。
2025-03-13 21:17:37
261
原创 Day14-代码随想录-反转字符串344+反转字符串II541+替换数字(ACM模式)+反转字符串中的单词151
重在怎么实现这三个操作,使用双指针操作这道题我做了很久,也看了很久别人做的代码,发现自己之所以一直不太明白快慢指针在里面如何操作,后面反思是因为自己忘记了。
2025-03-11 15:58:29
133
原创 Day13-代码随想录-三数之和15+四数之和18
四数之和题目如下所示(跟三数之和的解法差不多,只不过多了一层循环)这道题主要的难点就是怎么去重,但这个又是最重要的。
2025-03-10 16:10:36
206
原创 Day12-代码随想录-四数相加II454+赎金信383
1)计算A,B两个数组元素之和,并将其存入map(这里需要注意的是:和是有可能重复的,如果作为键的话,可以利用value来记录出现的次数,如:前面已经出现过相同的和也就是键,直接对其value累加即可);又积累一个map函数的用法:map.getOrDefault(key,0)-获取指定key对应的value,如果找不到key,则返回设置的默认值0(可以自己设置,不一定为0)原来做题的思想:(虽然也能通过,但相较于随想录给出的代码还是稍微复杂了一些)2)计算0-C-D的值,看能否对上面存入的键进行匹配。
2025-03-09 20:26:15
220
原创 Day11-代码随想录-快乐数202+两数之和1
这时候HashSet就派上用场了,将每个平方和新生成的数sum添加进集合Set里,如果不是快乐数那么sum在无限循环过程中势必会再次出现,利用set.contains(sum)提前判断就可以终止非快乐数的循环,返回false。这道题一看就很简单,直接暴力解法就可以得出了,但这不是我们的目的,很显然暴力解法的复杂度是O(n^2),在这里需要探索复杂度更低更简单的解法。另外需要注意的点就是:用到模块化的方法,可以将这个新数生成的过程整理成一个函数/方法来调用,这样代码更简洁也更易懂。
2025-03-08 18:05:14
141
原创 Day10-代码随想录-有效的字母异位词242+两个数组的交集349
思路:题目规定了两个字符串里面都是小写字母,可以定义一个26位的记录数组来记录第一个字符串每个字母出现的次数,然后在这个基础上,再去判断第二个字符串每个字符串出现的次数,如果两个字符串异位,那么记录数组每个字母的记录都应该为0.这是用。感觉自己学的知识好像是孤立的,看视频学的java记录的知识点真的是一不用就不会,看到这道题都不会想到去用Set和HashSet,只是一昧地用数组,但数组又很难解决元素的重复性,写起来就把简单的事情给复杂化了且算法复杂度还高。
2025-03-07 17:42:22
196
原创 Day09-代码随想录-链表相交02.07+环形链表II142
再看示例图会发现,两条链表其实是靠右对齐的,如果让长链表先移动它的指针到短链表指针的头指针的位置,两个链表就可以同时移动,然后判断是有相同的指针相交了。快指针走过的节点:x+y+n*(y+z),而快指针走过的节点数是慢指针的两倍,所以2*(x+y)=x+y+n*(y+z),即:x=(n-1)y+nz,当n=1时,x=z,n>1,相当于快指针多转了(n-1)圈才遇到慢指针也就是环入口。(3)计算出链表长度差,让长链表先移动它的头指针(长度差次);(2)定义和判断出正确的长链表是两个链表中的哪一个;
2025-03-06 21:59:03
207
原创 Day08-代码随想录-删除链表的倒数第n个结点19
for循环的遍历,不就意味着指针在一个一个的移动吗,使用双指针(快慢指针),让快指针始终比慢指针快n个节点,然后再同时移动的话,当快指针移动到链表的null时,慢指针就会到需要删除的倒数第n个元素的前面一个节点,这个想法真的是妙哇,这样不就能删除倒数的链表元素了。思维误区:刚看到这道题的时候一直在纠结倒数第n个元素的指针要怎么获得,觉得一定要像数组那样获得明确的索引才行,所以还用循环遍历链表得到链表元素个数,然后再来找倒数的索引,所以就想的更复杂了,然后做不出来。
2025-03-06 10:03:32
529
原创 Day07-代码随想录-反转链表206+两两交换的链表24
思路:学会定义多个指针,临时指针以及虚拟头指针,思路其实比较简单,主要就是可能会因为指针的不断变化,搞混顺序,易错点就是等号左右两边指针是等价的,变换指针之后原先的next就不能再用了,所以为避免出错,最好每个步骤画个图,搞清楚指针的动态。创建一个新指针来辅助反转的时候,总是顺序和逻辑搞混,导致很简单的一个题都写不完整。③还需要一个临时指针temp:否则无法更新和移动prev和current指针的位置;②引入新指针:prev,也就是在current前面的一个指针(初始化为Null);
2025-03-04 22:11:22
115
原创 代码随想录-Day06-移除链表元素203+设计链表707
这道题目几乎涵盖了链表的基本操作,本身自己对链表就不是很熟悉,没写过关于链表的代码,所以需要每行代码都要搞懂,思路:对链表进行操作,一般都是设置虚拟头结点,以及遍历的时候会在创建一个新的指针;(存放指向下一个节点的指针),最后一个节点的指针域指向null(空指针的意思)。(2)构建虚拟的头结点,这样就不用区分删除头结点和普通结点了。链表的入口节点称为链表的头结点也就是head。在添加元素时,需要注意指针指向的先后顺序。,每一个节点由两部分组成,一个是。(4)在最后一个元素后增加。
2025-03-03 20:31:07
185
原创 代码随想录-Day04-区间和(ACM模式)
思路:刚开始想的就是直接暴力解,直接累加这个区间不就好了,但这会遇到一个问题,如果查询次数比较大的话,时间复杂度会很大,每次都要从0到n-1,这会超时,所以想到前缀和来解决这个问题。上面这个图显而易见,下面p[i]存储的就是上面数组vec的区间0-i的累加和。代码比较简单,但主要之前自己联系java代码的时候连接了通义,打出一两个字符他就能直接输入,会导致自己直接手撕的话会很慢,想不起来具体要怎么写。与此同时,代码随想录出的这道题不同于力扣上直接有测试用例和框架结构的,它使用的是。
2025-03-01 21:21:13
240
原创 代码随想录-Day03-长度最小的子数组209+螺旋矩阵II59
刚开始是一点思路都没有,不敢想的太复杂,也想到每个的规律是i++,j++,然后i--,j--,但并没有想的那么深层次,最后还是放弃,看了解析才知道怎么做,但也想了很久,感觉即使现在记住了,过一段时间再来看还是会不知道怎么做,所以需要温故知新。①起始位置和结束位置都先从数组第一个索引 开始,然后固定起始位置,开始向后滑动结束位置,直至窗口的和大于目标值,记录此时窗口和和窗口长度(取最小值);②此时,需要在当前窗口向前滑动起始位置(缩小窗口),记录窗口长度和和,直至和小于目标值;注意审题:长度最小的。
2025-02-28 17:36:19
229
原创 代码随想录-Day01-二分查找704
(2)这肯定是需要循环的,要一直变换数组的区间来不断判断,一般使用while循环(我之前想的是for循环,但这个的话太占内存了,且会无效访问很多次,效率低),这时候循环结束的条件就显得尤为重要,并且有两种情况:①左闭右闭:left<=right;(1)首先这是一个数组,有头有尾,可以定义头部和尾部,以及中间部分(以前的想法就是数组长度/2,但没有考虑过是奇数的情况该怎么办,初始均分之后没找到目标值,又应该怎么二分,所以需要定义数组的头部和尾部,让他们动态变化,变换查找的区间);
2025-02-26 21:58:22
312
原创 Day4-计算机基础学习
1.过程调用的机器级表示:在主函数里执行相加函数,总结就是先保护原现场(地址),然后去临时执行另一个事件(创建的局部空间),再将计算得到的结果通过保存的地址回到原现场。相当于人做一件事情,被打断了,先去完成更紧急的事情了之后再回来继续做事。关于递归、选择、循环过程的机器级表示其实与上面的过程调用类似,不是重点,了解即可。
2024-12-19 21:19:08
258
原创 Day3-计算机基础学习
这节主要是关于计算机的各种运算运算的本质其实就是将所有的逻辑表达式转化为逻辑电路,都可以用最基本的门电路(与门、或门、非门)组合而成所有的算术运算都是实现的!!!
2024-12-19 11:27:19
256
原创 Day1-计算机基础学习
今天开始每日利用闲暇时间学计算机基础,为之后学习Java和刷八股文奠定基础,毕竟自己对于计算机是真的很小白,什么都不懂,先一步一步慢慢来吧书籍《计算机是怎样跑起来的》+视频《计算机系统基础》同步进行今天学习的是。
2024-12-01 11:25:49
316
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人