一个算法笨蛋的2月leetCode刷题日记

类似文章

一个算法笨蛋的2021年11月leetCode刷题日记

一个算法笨蛋的2021年12月leetCode刷题日记

一个算法笨蛋的2022年1月leetCode刷题日记

一个算法笨蛋的2022年2月leetCode刷题日记

一个算法笨蛋的2022年3月leetCode刷题日记

时间情况
2022年2月7日
【474】一和零(思路:同样是动态规划中的0-1背包问题,我想到要用三维数组,但是想不到状态转移方程,脑子里还想着要给这个三维数组进行初始化,发现不现实,然后就gg了。看题解确实是用三维dp数组,方法同样巧妙,dp[i][j][k]代表的是前面k个字符串,有j个0,k个1,值为子集的长度。在一重循环中获取当前字符串的0的个数zeros和1的个数ones,在三重循环中进行判断选择放入背包或者不放入,不放入就是dp[i][j][k] = dp[i-1][j][k];放入(判断能否放入,即j >= zeros,k >= ones)就是dp[i][j][k] = Math.max(dp[j][k],dp[j-zeros][k-ones] + 1) )
2022年2月8日
【494】目标和(思路:回溯方法好理解,也好些,动态规划方法无法理解,看题解看不明白,不看了,以后再看)

【518】零钱兑换 ll(思路:这题就好理解多了,不过还是不能都独自做出来,动态规划的题目太难了,太多细节了,思路太清奇了,不过也有我脑子不够的原因,我看其他人做十几题动态规划的题都开始明悟了,而我还是局限在写不出状态转移方程的这一步,看了题意恍然大悟,不看题意难若登天,悲哉。每一题都要按小时来计算时间,太难了)

【70】爬楼梯(思路:好吧,这题太经典,太简单了,轻易做出来了,但是这题不算不算,我还是菜鸡,我还是做不出动态规划)
2022年2月9日
【118】杨辉三角(思路:嘿嘿,这题我做出来了,虽然这是动态规划里极少数的简单题,基本就是总结规律的题目dp[i][j] = dp[i-1][j-1] + dp[i-1][j]。但是毕竟做出来了,花费的时间也比较短,哈哈哈哈哈,舒服,耶斯莫拉)在这里插入图片描述

【119】杨辉三角II(思路:这题也做出来了,由于题目的进阶要求是空间复杂度为O(n),所以必须进行压缩,将二维数组压缩为一维数组,为此我花费了接近一个小时才做出来,使用一个额外变量temp保存当前即将被改变的旧值,用于下一个计算使用,也是使用了双重for循环,在第一层循环初始化temp=1,后续在第二个循环只有如下两行代码:dp[j] = temp + dp[j]; temp = dp[j] - temp; 我感觉直接设计 的非常巧妙,一般人未必能跟上这思维,哈哈,好嗨哟)

【121】买卖股票的最佳时机(思路:这题也做出来了,连续四题简单动态规划题做下来,信心大增啊,虽然感觉这些题感觉都不算严格的动态规划题(这题我就没用动态规划的方法)。我这波就是利用三个额外变量,进行一次遍历,计算得出。三个额外变量分别是前i个价格中的最小值min,前i个价格中的最大差值max,第i个价格与min的差值temp,在遍历过程中实时更新min,max,最后返回max即可)

【22】括号生成(思路:果然一做medium题就原形毕露了,根本遭不住呀,看着这题一点点思路都没有。百度后得知的思路:当i = n时,组合一定以“(”开头,只需要确定“)”结束的位置,并且"("、")"之间的括号组合必须为合法的(dp[a]),然后只需要将剩下的n - 1 - j个括号组合放在右侧即可(dp[b]),所以可以推导出dp[n] = “(” + dp[a] + “)” + dp[b];(a = 0 ~ i-1,a + b = n - 1)抱歉,这种思路我完全想不到,脑子只有一片空白,毁灭吧。)在这里插入图片描述

【55】跳跃游戏(思路:这次的medium的我做出来了,嘿嘿,第一个自己做出来的medium动态规划题,舒服。但是我的效率比较差,时间空间都低于10%,后来自己琢磨了一下,第二层遍历使用倒序遍历应该可以优化一些。结果证明我琢磨对了,从700ms左右优化到了50ms左右,但是耗时击败也只是从低于10%变成了15%。我看题解,用贪心算法是最快的,只需要2ms左右,只用了一层循环。不过我看其他人的动态规划解法,貌似还没我优化后的解法好,无论是代码量还是耗时,我都远远超过,嘿嘿)
2022年2月10日
【63】不同路径II(思路:这次的medium级别的题我也做出来了,不过有一个重要因素,因为这题是【62】不同路径的进阶题,所以理论上的状态转移方程都一样,所以这题的难度就大大降低了,我的解法还是利用了二维数组,但是我看题解进行了状态压缩,利用滚动数组的思想,将状态压缩成了一维,我还有点看不懂这解法,有点菜了)

【64】最小路径和(思路:这大概是我做过最简单的medium级别的动态规划题了,轻轻松松10分钟不到一次运行成功,简直不要太简单,比easy级别的杨辉三角还简单的多,也许是我变强了?!不过吸取上次我做【63】不同路径II的教训,感觉应该还可以进行状态压缩,我还是用的二维dp数组,不过看了所有的Java题解,都是用的二维数组,官方题解倒是提了一句可以优化为一维,不过没写出题解,遂不了了之)

【91】解码方法(思路:这题我通过了90%的用例,只有在一种情况下无法通过,没法子,感觉要概括这种情况有点复杂,算法不可能如此不优美,肯定是思路错了,所以就把代码全删了,看了题解,果然我的思路有问题,根本不需要那么多if的例外情况,但是大体思路上还是一样的,就是表达方式上天差地别,没做出来)
2022年2月11日
【91】交错字符串(思路:这题研究了一上午,代码改了又改,还是无法通过部分测试用例,跟上一题一样。我发现我是直接妄图使用一维来解决,所以状态定义的也不太好,主要是前面一直没有考虑到两个字符串长度不同的情况,改来改去,通过的测试用例越来越多,但是当我发现无法解决长度不同的问题的时候,我就知道我失败了。正确的状态定义应该是dp[i][j]代表s1的前i个字符,与s2的前j个字符,是否符合s3中的前i+j-1个字符为交错字符串。)
2022年2月12日周末,沉迷王者
2022年2月13日周末,沉迷王者
2022年2月14日busy with work
2022年2月15日busy with work
2022年2月16日
【120】三角形最小路径和(思路:nice,这题花费些时间,完美写出来了,这是medium题,也是正规的动态规划题,哈哈,真真切切的做出来了。说一下我的思考历程,首先肯定是要定义状态,也就是先假设是二维dp[i][j],(我无论啥题,都是先假设二维dp,定义不出来就再尝试一维,三维来定义),然后尝试用一句话表达出来,例如:dp[i][j]代表的是在第i行,第j列时,最小的路径和。读下来发现,非常通顺且合理,那就是这样定义了。ps(我一开始的解读是前i行的第j列的路径和为dp[i][j],然后就发现j表达不出含义,于是又尝试去使用一维dp去了,然后再做的过程中,发现一维不行,就又重新从二维出发,最终才确定了状态)。状态确定后,就画个dp表推导下,于是我发现了猫腻,dp[i][j]有可能是dp[i-1][j]或者dp[i-1][j-1]推导过来的(用dp表推导下,就能够发现),所以自然而然的,就推导出了状态转移方程,篇幅有限,还有非常多边界条件和初始化,就不表述了,用一句话概括就是,看着推导出来的dp表来写。)
2022年2月17日
【122】买卖股票的最佳时机 II(思路:就这?可不要太简单,还是medium题呢,相对于【121】买卖股票的最佳时机,区别就是这题可以多次买入卖出,【121】只能买卖一次,但是完完全全没对我造成干扰,这就是简单的数学归纳,我依照着自己总结的动态规划题目的规律,先找状态,再确认dp数组的含义,然后总结状态转移方程,然后就完成了。这题的dp数组可以表示为:dp[i]表示在前i天,能够获取到的最大利润。状态转移方程我一下子就找到了dp[i] = prices[i] - prices[i-1] + dp[i-1],简单,写完一个字符都没改,直接提交通过)
2022年2月18日

【123】买卖股票的最佳时机 III(思路:这题还是比较难的,无愧于hard题的难度,我的思路与题解完全是天差地别,我在想着一步到位,不想局限于两次,即使k次也可以的计算的算法,最后发现我能力有限,做不出来。我看题解的主要思路就是将状态分为四个:第一次买入,第一次卖出,第二次买入,第二次卖出。然后使用两个一维数组buy[],和sell[]实现)

【188】买卖股票的最佳时机 IV(思路:这题跟【123】是一样的,不过我在【123】已经尝试用k次来解答,所以区别不大,基本可以说是照抄就行,不过理解起来是真的难以理解)
2022年2月19日周末,无趣
2022年2月20日周末,无趣
2022年2月21日
【309】最佳买卖股票时机含冷冻期(思路:同样是股票的经典6题之一,唯一需要注意的就是隔一天才能交易,那么就需要处理好边界问题,i-2的情况得考虑清楚)

【714】买卖股票时机含手续费(思路:同样是股票的经典6题之一,我已经腻味了,由于在【123】没做出来,导致后续的股票题我都是照抄【123】,关键是我对于这些题的压缩降维还没搞明白,就越做越烦,甚至不想碰了)
2022年2月22日
【131】分割字符串(思路:这题唯一的两个作用就是,其一:我还是个大彩笔,其二:我对于回溯非常陌生,是薄弱点。嗯,我做不出,冥思苦想,根本没办法做到获取所有分割的可能,或许是被前面做的题局限了吧,老是想着dp[i][j]代表的是前i个字符。。。这种解释,居然没想到从全局出发,直接穷举所有分割可能,然后判断符合要求的可能存入list,这种方法很原始,所以还需要一些技巧,也就是回溯,回溯,回溯,回溯搞不明白的呀)
2022年2月23日
【139】单词拆分(思路:这题相当于做出来了吧,虽然没通过所有测试用例,但是思路,写法和题解都是差不多的,都是通过定义布尔类型的一维dp数组,通过双重for循环,枚举所有可能。我差就差在题解是在为true时才赋值,不会被后续的赋值覆盖,我是直接赋值dp[i] = dp[j] && wordDict.contains(s.substring(j,i),导致dp[i]只会被y最大时的dp[i]覆盖))

【152】乘积最大子数组(思路:没做出来,太菜了,利用两个额外变量max1,min1和max,分别赋值为1,1,Integer.MIN_VALUE。max1在nums[i]和nums[i]*max1中诞生,min1在nums[i]和nums[i]*min1中诞生,最大值在max和max1中诞生,如果nums[i]为负数,需要将max1和min1交换,最后返回max即可。好难理解啊,动态规划做了几十题了,还是接连做不出medium题,挫败)

【198】打家劫舍(思路:这题做出来了,虽然是medium题,但是没有那么多的弯弯绕绕,就是纯粹的动态规划题,不需要转那么多弯,按照动态规划的套路就很快做出来了,但是感觉也没那么喜悦,唉,前面几题太挫败了,状态转移方程是:dp[i] = Math.max(dp[i-2] + nums[i],dp[i-1]);做完后我又进行了优化,由于dp[i]只与dp[i-2]和dp[i-1]有关,可以利用滚动数组的思想,通过两个额外变量first,second,用于保存前面两个值,状态转移方程为:second = Math.max(first + nums[i],second))ps:写完看题解,感觉官方题解是抄袭我的,连first,second这种命名都一样😝

【198】打家劫舍 II(思路:哈哈哈哈,这题也做出来了,高兴,难度提升了一点,但是还是属于medium题,基本思路都是一样的,不过题目要求是所有房屋是围成一圈的,所以首尾两个房子不可兼得。然后我就想到,那不就思路清晰了:只需要用nums[]分别取两个数组,第一个数组没有nums[]的第一个数字,第二个数组没有nums[]的最后一个数字(这里推荐使用System.arraycopy()方法,条件复制数组不要太方便,一行代码复制数组),然后按照第一题的思路,分别取出两个数组能够偷取的最大金额,然后两个金额取最大那个就是结果了)
2022年2月24日
【221】最大正方形(思路:这题做出来了,但是解法不敢恭维,耗时击败7%,内存击败24%。勉勉强强过了,但是我确实是用了动态规划的解法啊,只是我的动态规划可能比较复杂,尴尬。先说一下我的思路:dp[i][j]代表的是当横坐标小于等于i,纵坐标小于等于j时,的最大正方形边长。最后的面积只需要边长平方一下就行。我的状态转移方程也有一点点比较麻烦,分为两种情况,篇幅有限,无法细说。只需要知道dp[i][j]是根据dp[i-1][j-1] , dp[i][j-1] , dp[i-1][j]推导出来的。我看官方的动态规划题解也就耗时击败68%,内存击败19%,也不咋地。但是看题解思路,比我的简单万万倍,无论是初始化还是状态转移方程,都碾压我)

【241】为运算表达式设计优先级(思路:这题做不出来,又是括号题,这题对我一点意义都没有,没有学习到如何东西,渣渣)
【264】丑数II(思路:两个思路,第一个思路是直接判断从1到Integer.MAX_VALUE中所有数是否为丑数,同时统计为第几个丑数,获取到题目要求的第n个数后,停止计算,直接返回该数,所以并不会真的计算从1到Integer.MAX_VALUE;但是。。。不出意外,超时了。第二种思路是根据丑数的定义:质因数只有2,3,5,所以只需要定义三个数,通过分别乘以三个之一找出相乘后的最小值,作为下一个丑数。可惜我想到了第二种思路,没整理明白具体改怎么写,于是GG了,没做出来)

【279】完全平方数(思路:已经连续好多题没做出来了呀,悲伤,这题我连状态都不敢定义,由于n可以非常大,那么,如果n为题目限定的最大值10000,那么就需要遍历极其多遍,就跟我做【264】丑数II的第一个思路一样看起来比较蠢,所以就卡住了,谁又能料到这题居然就得这么定义状态,唉。我们只需要遍历所有比n小的数,假设当前n为i,比i小的数为j,则需要j*j小于i,通过计算遍历j过程中的最小值+1就是dp[i]的答案)
2022年2月25日
【313】超级丑数(思路:这题也没做出来,是丑数的进阶,有未知个质因数,所以只能用循环遍历质因数数组,然后按照丑数的做法,原来通过手动定义num2,num3,num5,现在也是通过数组,所以除了dp数组,还需要额外定义两个额外数组,长度都为质因数数组的长度)
2022年2月26日周末,充钱玩游戏使我快乐
2022年2月27日周末,充钱玩游戏使我快乐
2022年2月28日
【322】零钱兑换(思路:这题做出来了,medium题。这题其实就是凑零钱,但是关系不大,因为我从来不会去可以记住这题的解法、状态、状态转移方程,完全相当于做新题,一开始思路不太清晰,但是按照框架去套,写着写着就清晰了,这就是框架的魅力,强。状态转移方程为:Math.min(dp[i],dp[i - coins[j]] + 1),简单)

【337】打家劫舍 III(思路:这题不会,没做出来。看题解的思路是通过1个容量为2的一维dp数组,通过一个后序遍历方法,dp[0]存储的是选择当前结点时的最大价值,dp[1]存储的是不选择当前结点时的最大价值。只需要在这两种情况中选出最大值即可。选择当前结点的情况就是:当前结点的值,加上其子结点不选时的值node.val + left[1] + right[1];不选择当前结点的情况就是:左子结点选和不选的最大值,以及右子结点选和不选的最大值相加,得到的就是当前结点不选的最大值。巧妙啊,可惜我想不到)

2月结束,才做了30题,既有工作忙起来了的原因,也有动态规划的题动不动就是按小时计,同时也有我效率低的原因,唉
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

三七有脾气

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值