- 博客(26)
- 收藏
- 关注
原创 CodeTop100 Day25
标准dfs题,值得注意的是dfs里面要设置标记位置,也就是沉岛,遍历到该位置就设置为0,num++,这样之后的就不会出错和重复计算了。该题最显然的做法是找到中点然后将左半部分反转然后比较,上述代码做到了边反转边移动,然后分析链表长度问题,最后比较两部分。该题采用贪心算法,意思是第二天比第一天多就卖,否则就不卖,当然套之前的dp状态模板也是能写的就是很麻烦。简单DP,走到该位置的时候,如果不是最上方或者最左方,则一定是从上方或者左方更新而来。给出贪心策略,然后排序数组,最后拼接。79、岛屿的最大面积。
2025-06-09 14:20:14
583
原创 CodeTop100 Day24
首先将所有的数存入hashset,然后遍历每个值,先判断该值是否为连续序列的起点,比如上述例子[100 4 200 1 3 2] 遍历到100,发现hashset中不存在99,就开始找从100起始的序列,while循环一直找100++,用longest更新最大值,发现最大为1,遍历到1的时候,发现是起点,则找2,3,4。起点位置路径为grid[0][0],最上方和最左方,只能从上个位置递推,否则就是求上方和左方的最小距离+该位置的值,最后输出dp[m-1][n-1];73、最小路径和64。
2025-06-06 13:57:14
422
原创 CodeTop100 Day23
(rand_X() - 1) × Y + rand_Y() ==> 可以等概率的生成[1, X * Y]范围的随机数。走到i,j位置只需要考虑,该位置左边,上边,斜上边的最小值+1就是边长,每次遍历记录max值,使用辅助栈模拟,如3[a2[c]b]-> 3[accb] ->accbaccbaccb。已知 rand_N() 可以等概率的生成[1, N]范围的随机数。该题的dp定义为以该位置为正方形的右下角能形成的最大正方形的边长。67、 用Rand7()实现Rand10()72、搜索二维矩阵||
2025-06-05 10:47:30
436
原创 CodeTop100 Day22
首先是根据对角线进行替换:123 456 789->147 258 369然后首尾交换 741 852 963。典型的回溯题,有很多类似的模板,但是要想一想是否可以重复使用,重复使用进入递归还是i,不能重复就是i+1。很显然的思路是对每个节点计算左右子树最大高度,求得每个节点的直径,然后定义一个变量每次更新最大值。想明白它是怎么旋转的,规律是什么。
2025-06-04 13:40:10
284
原创 CodeTop100 Day21
二叉树递归接口,传入两个起始节点开始遍历,判断null情况,只有两个节点同时为空才返回true,否则一旦有节点为空就返回false,判断传入节点是否相同就行了。迭代和递归写法都要会,迭代要注意,一直将根和左节点加入结果和栈中直到为空,然后再考虑右节点。递归返回max(左子树最大深度,右子树最大深度)+1。今天这三题是二叉树中简单的题了,但也算是常考题。62、二叉树的前序遍历144。63、二叉树的最大深度104。61、对称二叉树101。
2025-06-03 13:36:03
314
原创 CodeTop100 Day20
尽量避免用库函数,这里采用双指针做法,先去掉头尾部空格,左指针从最右边向左移动,然后将i,j+1加入字符串,然后移动i指针到下一个单词,j指针跟随i进入下一轮循环,最后减去最后个空格输出即可。模拟题,遍历一下路径,将结果放入ans,val值是当前节点的上一层,递归还是很清晰的。具体思路就是维护一个最小栈存放当前最小值。当然这里可以用数组代替,空间可以更小。60、求根结点到叶子节点之和。58、翻转字符串中的数字。
2025-06-02 16:33:04
293
原创 CodeTop100 Day19
写一个递归函数,build(preorder,0,preorder.length-1,inorder,0,inorder.length-1);接收的参数是先序遍历数组,起始位置,长度,中序位置与长度,递归出口是起始位置不能超出数组长度。最上根结点肯定是先序数组的起始位置也就是preorder[0],然后从中序数组找到根的下标,计算长度,然后递归,root.left=build(左) root.right=build(右) 返回root。过于经典的模板,遍历,退回,输出答案。前序是根左右,中序是左根右。
2025-06-01 10:32:01
266
原创 CodeTop100 Day18
滑动窗口题,定义两个map储存字符,left=0,right=0,标记位valild=0,外层循环是right<s.length(),右指针移动,如果当前字符符合t数组中的字符串,则窗口map将该值加进去,如果窗口中的对该字符等于元字符所需要的个数,valid就++,例如,t中A需要1个,right找到满足包含t字符串的子字符就停止移动,然后收缩left,将左指针指向的字符串移走,然后更新长度,每次记录下最短的长度和开始位置,返回最小字串即可。这里定义dp[i]为以i-1位置结尾的最长合法括号字串。
2025-05-31 19:38:56
446
原创 Leetcode-拓扑排序
将supplies中的食材加入队列进行拓扑排序,符合入度为0的食物就能输出。拓扑排序,总的来说是每次都将入度为0的结点删去直到该无向图为空。
2025-05-30 14:03:33
83
原创 CodeTop100 Day17
本质就是让数值放到自己的位置,比如1就是索引0,2就是索引1,然后遍历一遍数组将每个值放入自己的索引位置,主要逻辑是,当nums[i]>0且nums[i]<=数组长度,并且该元素不在自己的位置就进入循环,交换位置,swap(nums[i]-1,i),交换完并不退出循环,看看交换后在该位置的元素是否是他的位置,继续交换直到nums[i]不满足要求,然后遍历一遍nums,如果该位置的值也就是。迭代法:遍历coins数组,状态转移方程为dp[i]=Math.min(dp[i],1+dp[1-coin]);
2025-05-30 10:37:22
525
原创 CodeTop100 Day16
状态转移方程为当在第i个台阶的时候,这时候有两种方法可以到达i台阶,一种是从dp[i-1]位置走一步到达i,另一种是在dp[i-2]位置走两个台阶到达i位置,所以dp[i]=dp[i-1]+dp[i-2]两种之和,定义初始变量dp[1]=1,dp[0]=1返回dp[n]即可。模拟题,根据题意先根据字符.分割为字符串数组,然后定义两个指针i,j,从0开始遍历字符串数组,a,b=字符串转整数,如果a!=b判断大小返回1或者-1,然后i++,j++,将a,b重新归零判断即可。
2025-05-29 17:46:07
376
原创 CodeTop100 Day15
举个例子,当n=2时候,dfs有两种路径,dfs(2,2,"")->dfs(1,2,"(")->dfs(0,2,"(")->dfs(0,1,")")->dfs(0,0,")")也就是(()),第二种是dfs(2,2,"")->dfs(1,2,"(")->dfs(1,1,")")->dfs(0,1,"(")->dfs(0,0,")")也就是()(),明白这个例子上面的也就明白了。采用二分法,left=0,right=x,当左右指针差大于1就进入循环,mid=(left+right)/2;
2025-05-28 20:00:00
1003
原创 CodeTop100 Day14
sortlist()实现:处理出口,找中点,left部分递归头节点,right部分调用中节点,最后merge这两部分,merge实现,定义哨兵节点,res节点,左值小于右值,res.next=left,否则就是res.next=right。找规律:比如13542的下一个排列是什么,先找到最后一个升序的位置,也就是3这个数字,然后右指针找到第一个比3大的数字就是4,两个交换得到14532,这样肯定不是下一个排列,然后将4后面的数字反转,得到14235就是正确的排列了。
2025-05-27 20:00:00
172
原创 CodeTop100 Day13
null){将root压入栈中,root=root.left},将左边节点都压入栈,然后将栈顶元素出栈放入res中,然后遍历右子树root=root.right,最后返回res。递归法:dfs(root,res),root==null,return 递归遍历左dfs(root.left,res) 根:res.add(root.val) ,右:dfs(root.right,res)出口root==null return 当depth==ans.size() ans.add(root.val)
2025-05-26 20:00:00
268
原创 CodeTop100 Day12
要想删掉倒数第n个结点就得直到倒数n+1个结点的引用,但是如何一次遍历得到呢,这里就利用了巧妙的方法,设置链长为m,找倒数第n个节点,设置两个指针变量,P1,P2,P1先走n个节点,此时P1还剩m-n距离,当P1走了n个节点时候,两个指针一起走,当P1走完距离时候,这时候P2走了m-n的距离,这时候P2的指针离空指针的距离为n也就是找到了倒数第n个节点,然后就可以把倒数第n-1的该节点删除,p2.next=p2.next.next。34、删除链表的倒数底n个结点。35、最长公共子序列。
2025-05-26 13:26:05
325
原创 CodeTop100 Day11
返回ans,以当前图作为例子来解释,ans在root等于20的时候达到最大,也就是ans=left+right+root.val=15+7+20,此时遍历的时候ans达到最大,向上递归时候返回以20为节点的最大单链,也就是return max(20+max(15,7),0)此时是35,所以当-10为root时候右边链就是35,左边链是9,最后是ans=35+9+(-10)=34,此时ans并不能更新,因为之前的ans已经是最大了为42。个字符不一样,就得进行替换操作,此时操作次数要在。
2025-05-26 10:16:35
1107
原创 CodeTop 100 Day10
这道题就是找规律题,找到通项公式water[i],在i位置的时候有多少水,这个时候就多猜想多写通式来验证是否正确,左边为1,右边为1,中间为0,中间就能存水,左边为1,右边为0,中间为0就不能存水,左边为1,右边为2,中间为0,只能存1的水,可以想到,左边的最大和右边最大的最小值可以存水,water[i]=Math.min(Math.max(0..i),Math.max(i..end))-height[i],发现通项确实是这样。找到链表环的起点,若没有就return null。就是将重叠的部分合并。
2025-05-23 15:12:41
564
原创 CodeTop100 Day9
假设两者有公共交点c,a链表非公共位a-c,b链表为b-c,a走到 a+b-c时候第二次遇到公共交点,b第二次遇到公共交点为,b+a-c,两者走过的距离都为a+b-c,所以也就能同时到达。如何找到相交的链表呢,两个链表同时遍历,a链表遍历完就遍历b链表,b链表遍历完就遍历a链表,如果存在相交节点就退出循环,同时遇到null也会退出。所以实现三个API即可,找中点使用快慢指针就可以,反转链表写了很多次了,交替连接也比较简单,设置暂存节点然后连接即可。意思是‘12’+‘13’=‘25’,但是要考虑进位问题。
2025-05-22 19:25:31
439
原创 CodeTop100 Day8
k为链表的个数,首先定义一个哨兵节点,还有一个cur节点,cur=dummy,然后将每个链表的头节点放入堆中,进入循环,当堆不为空,cur.next=堆顶元素,如果堆顶元素的next有值就放入堆中,否则就跳过,p=p.next,最后返回哨兵节点.next即可。所以子问题是,当枚举以i为结尾时候,j的范围为0-i,当nums[j]<nums[i]时候,nums[i]可以选择之前以j为结尾的最长子序列+1递推过来,然后从0-i中选择最大的dp[i]进行递推。经典的dp题,核心是怎么定义dp,怎么找到子问题。
2025-05-21 16:43:11
711
原创 CodeTop100 Day7
首先定义哨兵节点,还有暂存节点,暂存节点定义到需要反转的前一个结点,然后就跟反转链表I一样了,反转right-left+1次后,暂存节点.next也就反转后最后一个节点的next=后面不用反转的第一个节点,暂存节点.next等于pre节点也就是遍历到最后一个要反转的节点,最后返回哨兵节点.next就ok。head.next=后继节点,返回last;如果left==null,直接返回右子树的最近,right==null,返回左子树的最近。1、若两节点都在以root为根的树中,函数返回两个节点的最近公共祖先。
2025-05-20 18:02:04
414
原创 CodeTop100 Day6
进入循环判断slow==fast,相同返回true,否则返回false。判断链表是否有环,采用快慢指针来解决问题,可以这样想问题,一个指针移动到环中的某个结点,该指针相对于快指针不变的情况下,快指针一直移动就必定会相遇,所以有环。双指针,倒着遍历最大的数组,处理边界情况,然后将大值更新到后面就ok了。如果为左括号就压栈,栈不为空且最外面的字符符合该字符就出栈。最后判断栈为空,或者不匹配就返回false,否则为true。
2025-05-19 20:00:18
184
原创 CodeTop100 Day5
这类题都有模板,定义回溯API,定义访问路径布尔类型数组,API里面返回条件是二维数组中的一维数组长度等于nums.length,就加入结果,每次遍历路径将该路径记录,然后遍历完该路径进行回退,remove,前一个路径结点清空,遍历完返回结果就ok了。这个转移怎么理解呢,就是当天有股票是怎么转移的,没股票是怎么转移的,然后k的理解,转移时候最大k一定是从最大为k-1转移。dp[...][0][0]=0这时候没有交易且无股票为0,dp[..][0][1]=min 这时候不可能有股票为负无穷。
2025-05-18 16:00:55
631
原创 CodeTop100 Day4
看到有序就可以思考二分了,只不过变了一部分,所以要额外判断一下,根据nums[mid]和左右指针 和target值进行维护左右指针,分类讨论清楚就ok。维护一个hashmap,然后遍历数组维护map就ok了,但是要主要先判断再放,不然会重复。模板题:迭代BFS,每次出队就把该结点的左右结点存入队,然后模拟遍历就ok。递归:实现API,传入结点和当前深度,维护一个二维动态数组,然后模拟就ok。这题简直是英语词典的abandon。给一个拼凑的两个递增数,查找值。11、二叉树的层序遍历。今天的三题比较轻松.
2025-05-17 20:22:44
199
原创 CodeTop100 Day3
归并排序采用分支的思想进行排序:先递归,分成左半部分和右半部分,然后 合并这两个排序的数组,重点是怎么实现这个合并API, 当元素为一个时,直接返回,这里定义一个成员数组temp来当作辅助数组,然后定义左右指针,左指针为左边界,右指针为mid+1,遍历数组元素从左到最后,如果左指针超过左半边届,则该数组就更新为temp[右++],若右指针超越右边界则等于temp[左++],如果temp[左]大于temp[右]则数组更新为temp[右++]。babad -> bab 或者 aba。9、合并两个有序链表。
2025-05-16 14:47:11
156
原创 CodeTop100 Day2
具体做法先实现一个API可以反转区间[a,b)结点,递归出口是该节点为空,定于左右结点,右节点右移k步,若移动过程中为空,就直接返回左节点,之后令cur结点等于反转(左,右),左的next等于递归(b,k)然后返回cur结点就ok了;排序后,枚举数组元素,若nums[i]>0直接返回,然后每次移动左右端点,移动时候左右端点要去重,另外Arrays.asList方法使用后该数组就确定长度了;所以dp[i]=Math.max(nums[i],dp[i-1]+nums[i])就是想是否后面需要前面的值。
2025-05-15 20:25:50
225
原创 CodeTop100 Day1
查询排n-k位的数,定义左右指针,若左等于右,直接返回nums[k],这是递归出口,获得将左指针第一个数当做比标,左指针找到大于等于该数的,右指针找到小于等于该数的,交换两者,最后排出该比标的正确位置,左边是比该值小的,右边是比该值大的,如果n-k,小于第一次排后的右指针则递归区间左半部分,否则递归右半部分。滑动窗口题,保存一个字母数组,维护左右指针,当遇到重复的,左指针右移,将移动的字符串去掉,直到满足要求,每次遍历更新答案,直到右指针为右端点,输出最大值;淘汰机制,去掉最不常用的。
2025-05-14 19:38:51
553
1
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人