算法
文章平均质量分 57
Ning_SE
这个作者很懒,什么都没留下…
展开
-
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 · 402 阅读 · 0 评论 -
Leetcode-day28-贪心算法
贪心的思路是:curSum也就是当前剩余的油量如果小于0了,说明只能从i+1开始走。如果totalSum最终小于0,怎么走都无解。而且题目中说如果是有解,唯一解。原创 2024-08-20 22:23:53 · 475 阅读 · 0 评论 -
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 · 474 阅读 · 0 评论 -
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 · 1103 阅读 · 0 评论 -
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 · 421 阅读 · 0 评论 -
Leetcode-day26-贪心算法
找到每个阶段的局部最优,最后找到全局最优。举个例子:十堆钞票,每堆里面取一张,找最大金额。贪心先从每堆里面找出金额最大的,进而推出总体的最大金额。思路:贪心:先对两个数组排序,大尺寸的饼干尽可能去满足大胃口的小孩。需要注意的是这里内层可以用index,就避免了双层for循环这个题可以把数组中的节点按山坡画出来,按照题意,首先把数组中元素等于1,2的情况写出来,然后分析,可以把数组中的元素按照坡度画出来,如下图,其实就是找的山峰元素和最左和最右元素(元素个数大于3)。原创 2024-08-18 18:13:41 · 511 阅读 · 0 评论 -
LeetCode-day25-全排列
1. 前面的组合问题中,我们是要有一个startIndex数组的,它是用来判断下一层递归是从那个树开始取的,避免取到一些重复的组合,比如【1,2,3】 【2,1,3】,但是在排列问题中这样不是同一个排列。2.在排列问题中的关键是取过元素之后在递归中就不需要重复取了,比如只看最左外侧,如果不判断,取了1,然后又能取的话就出现了【1,1】。去重相似,不能对它进行排序,因为排序之后会造成出现不想要的结果,所以不能像之前的组合等问题一样用used数组,这个时候可以在树层做一个set,来记录树层中是否有重复。原创 2024-08-17 18:51:19 · 423 阅读 · 0 评论 -
LeetCode-day24-非递减子序列
1. 要去重,但是又不能对原数组进行排序,所以需要用新的排序方法,本层使用Set,此时是不需要在回溯中移除set中的元素的,因为下一层的时候已经新建了一个Set。2. 如何保证子序列是递增的?path.isEmpty() && nums[i] < path.get(path.size() - 1)看下面的图,只要所取元素小于子序列的最后一个元素,就continue。原创 2024-08-17 17:39:12 · 186 阅读 · 0 评论 -
Leetcode-day23-回溯-子集问题
首先要对数组进行排序,方便左判断,然后我们可以做一个flag数组来记录每个元素是否被取到了,如图所示如果是纵向,树枝被取到了,flag[i-1]是true,而如果是横向的树层则是false,因为已经被回溯了,这时候直接continue就可以了。首先要区分好树层和树枝,树枝上也就是纵向是可以重复取的,但是树层上是不能重复取的。这个问题就简单多了,以前找的是叶子节点,现在是要把所有节点都找出来。这个题也比较简单,有了前面的基础之后,其实就是多了一个去重操作。原创 2024-08-17 14:16:20 · 517 阅读 · 0 评论 -
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 · 593 阅读 · 0 评论 -
Leetcode-day15-二叉树
TODO。原创 2024-08-07 21:04:47 · 108 阅读 · 0 评论 -
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 · 403 阅读 · 0 评论 -
Leetcodeday13-二叉树
突然发现用二叉树用前序遍历(深度优先)特别好理解,因为基本只需要看根怎么移动,怎么操作,后面的交给左右子树去遍历操作,不过因为是先序,有些操作还是做不了,比如求树的最大深度,需要找到左右的最大深度然后+1,这时候得用后序。仿照前序遍历(深度优先)的代码来写,不同的是每个节点访问的时候不是把他打印出来,而是先把他存储起来,到叶子结点的时候再添加到集合中,最后返回集合的值。思路:定义一个函数,传入node,返回值int,如果该节点平衡则返回该节点的高度,如果不平衡则返回-1。//如果为空,直接返回。原创 2024-08-04 13:23:38 · 890 阅读 · 0 评论 -
Leetcode-day12-二叉树
用中序会比较绕,因为左根右,左子树反转完之后,根,把左子树反转到了右边,应该是左根左递归。2.确定跳出条件,左右有一个为空,false;都不空但是值不相等false,否则(值相等)进入递归。与最大深度的区别,最小深度是从根节点到最近叶子节点的最短路径上的节点数量。比较两个树内侧和外侧是否相等,所以需要后序遍历,左右子树都比较完了,看一下结果怎么样。1.确定参数和返回值,比较是否对称,所以传入左右两个数的头节点,返回Boolean。后序遍历,找到左右子树的高度,然后返回他们的最大值+1。原创 2024-07-31 11:33:01 · 238 阅读 · 0 评论 -
Leetcode-day11-二叉树
写完了递归算法, 运行的时候,经常会遇到栈溢出的错误,就是没写终止条件或者终止条件写的不对,操作系统也是用一个栈的结构来保存每一层递归的信息,如果递归没有终止,操作系统的内存栈必然就会溢出。确定哪些参数是递归的过程中需要处理的,那么就在递归函数里加上这个参数, 并且还要明确每次递归的返回值是什么进而确定递归函数的返回类型。借助队列,先把根节点放进去,用size记录每层的节点数,把每层的节点左右节点加入队列,谈对当前层的节点放入结果list中。在这里也就会重复调用自己来实现递归的过程。原创 2024-07-30 11:42:57 · 186 阅读 · 0 评论 -
Leetcode-day06-哈希表
思路:暴力解法那就是四个for循环去遍历了,时间复杂度是n的四次方。优化:要注意这个题的要求,是计算有多少个元组,也就是不需要去重,如果四个数组都全零,那各个数组的各个位置都可以算。所以这个题可以先把第一和第二个数组各个元素的和放到一个hashmap里,key存的是和,value存的是该和出现的次数。然后把第三个和第四个数组各元素的和放到另一个hashmap里,这样其实就是去找hashmap1里面和hashmap2里面相加为0的元素,把他们的value相乘。原创 2024-07-23 20:37:14 · 320 阅读 · 0 评论 -
Leetcode-day02-数组
1. 数组原本是有序的,注意可能有负数,所以不能直接按顺序排,但平方之后最大的数一定是在最左或者最右,所以可以用双指针来实现,分别指向最左和最右的元素,哪个元素大,就把哪个元素放在数组末尾,然后移动指针。思路:for循环走结束位置,窗口内的和如果>=target,那起始位置移动,同时把窗口内的和更新,记录最小长度。这个题主要是考察对于循环的把控,对于循环不变量的深入理解。假如我们做的就是左闭右开,那这就是我们的循环不变量。原创 2024-07-19 10:04:29 · 216 阅读 · 0 评论 -
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 · 322 阅读 · 0 评论 -
Leetcode-day04-链表
切入点:要交换那就得找到前一个节点,所以引入dummy node节点。然后就是画图示意一下,如果说偶数个节点,找完之后cur的next是null,如果是奇数个节点,则最后一个节点不需要交换了,就是cur.next.next==null。然后就是具体的交换逻辑了,注意其中修改指向之后可能造成后续节点找不到,所以得用temp节点提前保存。原创 2024-07-20 18:51:12 · 341 阅读 · 0 评论 -
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 · 280 阅读 · 0 评论 -
Leetcode-day05-哈希表
数组(数组下标做映射),Set,Map。一般来说如果哈希表大小确定,而且比较小,可以优先用数组,因为它比较快。其实就是判断都是两个字符串是不是都有相同的字母组成,顺序可以不一致。原创 2024-07-22 19:45:18 · 292 阅读 · 0 评论