自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(29)
  • 收藏
  • 关注

原创 Leetcode-day31-01背包问题

由dp[i - 1][j - weight[i]]推出,dp[i - 1][j - weight[i]] 为背包容量为j - weight[i]的时候不放物品i的最大价值,那么dp[i - 1][j - weight[i]] + value[i] (物品i的价值),就是背包放物品i得到的最大价值。3.dp数组初始化:dp数组的第一列,也就是容量为0,此时都是0。:由dp[i - 1][j]推出,即背包容量为j,里面不放物品i的最大价值,此时dp[i][j]就是dp[i - 1][j]。

2024-08-23 16:59:38 416

原创 Leetcode-day30-动态规划-不同路径

这个题动态规划的特征比较明显,我们就看终点,到终点的不同路径就等于要么从他上面一格往下走一格,要么从他左边一个往右走一格,所以可以得出递推公式。4.遍历方向,还是和上一题一样,不一样的是如果遇到障碍就直接这个位置置0,continue,不需要递推。3.dp数组初始化,和上一题不同的是第一行,或者第一列,如果中间已经有障碍那后面就都是0。2.确定递推公式,dp[m][n] = dp[m-1][n]+dp[m][n-1]2.递推公式,dp[m][n] = dp[m-1][n]+dp[m][n-1]

2024-08-22 17:07:15 490

原创 Leetcode-day29-动态规划

2.确定递推公式 到达第n阶要么是从n-1一步上来,要么是从n-2两步上来,所以dp[n] = min(dp[n-1]+cost[n-1],dp[n-2]+cost[n-2])2.递推公式,到第n阶楼梯只能从n-1往上一阶或者从n-2阶往上两阶,所以dp[n] = dp[n-1]+dp[n-2]1. 确定dp[] 的具体含义是什么,i代表什么,dp[i]代表什么。3.dp初始化 题目也给出了 dp[0]=0,dp[1]=1。3.初始化,dp[1]=1,dp[2]=2。这里用动态规划来做(也可以用递归)

2024-08-21 22:23:39 1133

原创 Leetcode-day28-贪心算法

贪心的思路是:curSum也就是当前剩余的油量如果小于0了,说明只能从i+1开始走。如果totalSum最终小于0,怎么走都无解。而且题目中说如果是有解,唯一解。

2024-08-20 22:23:53 488

原创 Leetcode-day27-贪心算法

那么根据 prices 可以得到每天的利润序列:(prices[i] - prices[i - 1]).....(prices[1] - prices[0])。相当于(prices[3] - prices[2]) + (prices[2] - prices[1]) + (prices[1] - prices[0])。贪心的思路,局部最优:让绝对值大的负数变为正数,当前数值达到最大,整体最优:整个数组和达到最大。假如第 0 天买入,第 3 天卖出,那么利润为:prices[3] - prices[0]。

2024-08-19 16:48:53 435

原创 Leetcode-day26-贪心算法

找到每个阶段的局部最优,最后找到全局最优。举个例子:十堆钞票,每堆里面取一张,找最大金额。贪心先从每堆里面找出金额最大的,进而推出总体的最大金额。思路:贪心:先对两个数组排序,大尺寸的饼干尽可能去满足大胃口的小孩。需要注意的是这里内层可以用index,就避免了双层for循环这个题可以把数组中的节点按山坡画出来,按照题意,首先把数组中元素等于1,2的情况写出来,然后分析,可以把数组中的元素按照坡度画出来,如下图,其实就是找的山峰元素和最左和最右元素(元素个数大于3)。

2024-08-18 18:13:41 529

原创 LeetCode-day25-全排列

1. 前面的组合问题中,我们是要有一个startIndex数组的,它是用来判断下一层递归是从那个树开始取的,避免取到一些重复的组合,比如【1,2,3】 【2,1,3】,但是在排列问题中这样不是同一个排列。2.在排列问题中的关键是取过元素之后在递归中就不需要重复取了,比如只看最左外侧,如果不判断,取了1,然后又能取的话就出现了【1,1】。去重相似,不能对它进行排序,因为排序之后会造成出现不想要的结果,所以不能像之前的组合等问题一样用used数组,这个时候可以在树层做一个set,来记录树层中是否有重复。

2024-08-17 18:51:19 436

原创 LeetCode-day24-非递减子序列

1. 要去重,但是又不能对原数组进行排序,所以需要用新的排序方法,本层使用Set,此时是不需要在回溯中移除set中的元素的,因为下一层的时候已经新建了一个Set。2. 如何保证子序列是递增的?path.isEmpty() && nums[i] < path.get(path.size() - 1)看下面的图,只要所取元素小于子序列的最后一个元素,就continue。

2024-08-17 17:39:12 194

原创 Leetcode-day23-回溯-子集问题

首先要对数组进行排序,方便左判断,然后我们可以做一个flag数组来记录每个元素是否被取到了,如图所示如果是纵向,树枝被取到了,flag[i-1]是true,而如果是横向的树层则是false,因为已经被回溯了,这时候直接continue就可以了。首先要区分好树层和树枝,树枝上也就是纵向是可以重复取的,但是树层上是不能重复取的。这个问题就简单多了,以前找的是叶子节点,现在是要把所有节点都找出来。这个题也比较简单,有了前面的基础之后,其实就是多了一个去重操作。

2024-08-17 14:16:20 537

原创 Leetcode-day22-回溯-复原IP地址

可以这样来看,我们只看这个树的纵向最左边,这条线代表的是startIndex从1开始,也就是第一个取了1,然后进入递归之后传给下一层递归的是i+1,也就是2,代表的是下一层递归要从【2,3,4】里面去取,取完2之后,也就是纵向最左边外层走完了,满足条件开始return,然后回溯,路径中去掉2,只剩1,此时return回去之后startIndex是2,for循环开始往下走++变成了3,也就是取到了【1,3】。那么回到切割问题,这时候我们就明确了,每次我们要切割的区间,其实就是【startIndex,i】。

2024-08-15 22:23:58 613

原创 Leetcode-day21-回溯

下面是用的startIndex来控制组合中的重复问题,注意递归的时候传入的是i,不是i+1,之前i+1是本元素只能用一次,这次的不限制。这里的叶子节点如果说总和找到了,加入path然后返回,如果是sum已经比Target大了,那直接返回。还是之前的思路,组合问题走回溯,抽象成树,横向遍历for循环,纵向遍历走递归,叶子节点就是答案。下面答案写完之后其实就差最后一步了,去重。下面答案做出来是排列的,题目要求是组合。其实有了前面题目的铺垫,这道题很容易可以把以下内容写出来。\TODO LIst res去重。

2024-08-12 22:56:29 875

原创 JAVA中的String三兄弟

String三兄弟

2024-08-11 22:54:19 349

原创 Leetcode-day20-回溯

回溯,for横向遍历,这个题里面,for循环横向遍历指的就是一个数字代表的那么多个字母,要遍历完,那纵向就是递归,递归的深度就是传入了几个数字,所以什么时候结束?这个题是找所有相加之和等于n的k个数,而且从1-9内找,和上一个题其实思路是一样的,只不过这个题的给定数组是确定的[1,2,3,4,5,6,7,8,9],然后多了一个结束条件(和是n),所以可以直接套上一个题的模版。通过这道题更深入的理解了回溯,什么时候用,能用很多层for循环完成的,比如这个,两个数字,用两个for,一百个数字用一百个。

2024-08-11 22:38:35 424

原创 Leetcode-day17-二叉树

TODO。

2024-08-07 21:06:46 150

原创 Leetcode-day15-二叉树

TODO。

2024-08-07 21:04:47 123

原创 Leetcode-day14-二叉树

添加元素:addFirst() addLast() offerFirst() offerLast() offer的API是成功返回true,失败返回false。移除元素:removeFirst() removeLast() 对列为空就抛异常 pollFirst() pollLast() 队列为空返回null。访问元素:getFirst() getLast() 队列为空抛异常 peekFirst() peekLast() 队列为空返回null。//思路:层序遍历,找最后一层的第一个元素。

2024-08-04 22:53:55 456

原创 Leetcodeday13-二叉树

突然发现用二叉树用前序遍历(深度优先)特别好理解,因为基本只需要看根怎么移动,怎么操作,后面的交给左右子树去遍历操作,不过因为是先序,有些操作还是做不了,比如求树的最大深度,需要找到左右的最大深度然后+1,这时候得用后序。仿照前序遍历(深度优先)的代码来写,不同的是每个节点访问的时候不是把他打印出来,而是先把他存储起来,到叶子结点的时候再添加到集合中,最后返回集合的值。思路:定义一个函数,传入node,返回值int,如果该节点平衡则返回该节点的高度,如果不平衡则返回-1。//如果为空,直接返回。

2024-08-04 13:23:38 906

原创 Leetcode-day12-二叉树

用中序会比较绕,因为左根右,左子树反转完之后,根,把左子树反转到了右边,应该是左根左递归。2.确定跳出条件,左右有一个为空,false;都不空但是值不相等false,否则(值相等)进入递归。与最大深度的区别,最小深度是从根节点到最近叶子节点的最短路径上的节点数量。比较两个树内侧和外侧是否相等,所以需要后序遍历,左右子树都比较完了,看一下结果怎么样。1.确定参数和返回值,比较是否对称,所以传入左右两个数的头节点,返回Boolean。后序遍历,找到左右子树的高度,然后返回他们的最大值+1。

2024-07-31 11:33:01 253

原创 Leetcode-day11-二叉树

写完了递归算法, 运行的时候,经常会遇到栈溢出的错误,就是没写终止条件或者终止条件写的不对,操作系统也是用一个栈的结构来保存每一层递归的信息,如果递归没有终止,操作系统的内存栈必然就会溢出。确定哪些参数是递归的过程中需要处理的,那么就在递归函数里加上这个参数, 并且还要明确每次递归的返回值是什么进而确定递归函数的返回类型。借助队列,先把根节点放进去,用size记录每层的节点数,把每层的节点左右节点加入队列,谈对当前层的节点放入结果list中。在这里也就会重复调用自己来实现递归的过程。

2024-07-30 11:42:57 201

原创 Leetcode-day10-栈和队列

思路,从左往右遍历,遇到+-*/,就弹出两个元素,并把运算结果压入栈中,其他的压入栈。2.String类型转int类型的时候用Integer.parseInt();需要注意的是:1. 先出栈的是右操作数,后出栈的是左操作数。

2024-07-27 21:58:01 183

原创 Leetcode-day09-栈和队列

栈是先进后出,队列是先进先出。要用栈实现队列的入队,出队等操作,入队其实很简单,就是入栈就可以,主要是出队,这里可以用两个栈,来实现队列的先进先出。进栈放到in栈,出栈的时候先把in栈里面所有的元素都放到out栈里,然后对out栈出,就实现了队列的先进先出的效果。其实用一个队列就可以实现栈,加入的时候直接加入队列,弹出的时候可以先把size-1的元素从队列里拿出来而且放到队列的末尾,这样拿出来的就是最后加入的元素,实现了后进先出。

2024-07-27 21:15:47 289

原创 Leetcode-day08-字符串

思路:java中用trim()去除字符串前后的空格,用正则表达式"\\s+"切割数组,因为可能有一个或者多个空格,反转之后用String.join(" ",partArr)在两两元素之间插入空格连接为字符串。思路:先整体反转字符串,然后把前后两个区间的字符串反转,就得到了右旋字符串。

2024-07-25 15:12:19 165

原创 Leetcode-day07-字符串

关键在于切片,其实每次是对2k的元素操作,所以每次可以让l+=2*k;再就是处理最后的元素时如果不满k个,则剩余的反转,可以用Math.min(r,n-1)原地反转,思路很简单,左右指针分别指在首尾,然后交换,移动指针。

2024-07-24 22:22:57 174

原创 Leetcode-day06-哈希表

思路:暴力解法那就是四个for循环去遍历了,时间复杂度是n的四次方。优化:要注意这个题的要求,是计算有多少个元组,也就是不需要去重,如果四个数组都全零,那各个数组的各个位置都可以算。所以这个题可以先把第一和第二个数组各个元素的和放到一个hashmap里,key存的是和,value存的是该和出现的次数。然后把第三个和第四个数组各元素的和放到另一个hashmap里,这样其实就是去找hashmap1里面和hashmap2里面相加为0的元素,把他们的value相乘。

2024-07-23 20:37:14 333

原创 Leetcode-day05-哈希表

数组(数组下标做映射),Set,Map。一般来说如果哈希表大小确定,而且比较小,可以优先用数组,因为它比较快。其实就是判断都是两个字符串是不是都有相同的字母组成,顺序可以不一致。

2024-07-22 19:45:18 302

原创 Leetcode-day04-链表

切入点:要交换那就得找到前一个节点,所以引入dummy node节点。然后就是画图示意一下,如果说偶数个节点,找完之后cur的next是null,如果是奇数个节点,则最后一个节点不需要交换了,就是cur.next.next==null。然后就是具体的交换逻辑了,注意其中修改指向之后可能造成后续节点找不到,所以得用temp节点提前保存。

2024-07-20 18:51:12 350

原创 Leetcode-day03-链表

初始化dummy指向head,pre指向dummy,node指向head(防止head丢失,其实可做可不做,因为这里有dummy)。让pre始终指向当前寻找节点的前一个。如果该元素不是当前要删除的节点,让pre和node往后走,如果要删,per.next=node.next;思路:单向链表,要让当前节点的next指向前一个节点,所以需要记录前一个节点pre,另外,如果更新了当前节点的next,则找不到原链表的下一个节点了,所以得有nxt记录原链表的下一个节点。

2024-07-20 17:24:24 289

原创 Leetcode-day02-数组

1. 数组原本是有序的,注意可能有负数,所以不能直接按顺序排,但平方之后最大的数一定是在最左或者最右,所以可以用双指针来实现,分别指向最左和最右的元素,哪个元素大,就把哪个元素放在数组末尾,然后移动指针。思路:for循环走结束位置,窗口内的和如果>=target,那起始位置移动,同时把窗口内的和更新,记录最小长度。这个题主要是考察对于循环的把控,对于循环不变量的深入理解。假如我们做的就是左闭右开,那这就是我们的循环不变量。

2024-07-19 10:04:29 225

原创 Leetcode-day01-数组

2. if(nums[middle]>target) 此时应该是right = middle 还是right = middle -1;答案是middle-1,因为是闭区间,已经判断了中间值不是target,查找区间就把它去掉。这个时候可以做带入,我的原则是[left,right]的区间,如果left==right是否满足该条件呢?2.while(left<right) 因为如果加了等于[1.1) 这是不合规的。3.right = mid 因为右开,(nums[mid]>target)

2024-07-17 18:39:35 335

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除