自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 leetcode|graph| 399. Evaluate Division 200. Number of Islands 130. Surrounded Regions

在boundary上或者和在boundary上格子相连的格子都不需要变成x。所以只需要思路同上地标记处所有不需要变的0就行(标记#之类的)。剩下的0就是要变成x的。dfs+memoization,需要用一个set记录某个点有没有作为起点使用过。用self,这样numIslands也可以access用dfs。所以这里grid[i][j]的改变会被带到外面。

2023-08-17 18:11:37 224

原创 221. Maximal Square 208. Implement Trie (Prefix Tree) 211. Design Add and Search Words Data Structur

node构建好之后,开始构建trie。所以constructor只需要initialize一个varible:root = new Node(): root本身是一个node,作为node就有自己的constructor。注意这个构造的结构:自己创造了node,node是一个class,class里面需要有variabl,function,和constructor。棋盘格里面的每个位置都是以该位置为左上角,最大的方形的边长,从下往上,从右往左,那么每个格子就是由右下角的三个决定的。选dfs还是bfs呢?

2023-08-16 15:04:38 182

原创 97. Interleaving String 72. Edit Distance 121. 122. 123

一个bottomup(棋盘从右下角外围逼近[0,0])如果横轴是string1的index i,纵轴string2的index j,那么,很奇妙的是i和j一起++(从右下角的格子看)的情况,是这两个char一致,共同开始比下一个字符/两个字符不一样但是我们选择replace。这种情况就是insert。持有分为两种情况:原本就持有,继续持有,那么profit不变,如果本来不持有,那么那么代表本次买入新的股票,要花钱,减array[i]。如果本来持有,本次就不持有了,代表卖了,赚钱了,加array[i]。

2023-08-13 18:38:37 288

原创 64. Minimum Path Sum 63. Unique Paths II 63. Unique Paths II

substring(first_position, length) 因为while里面最后得出的left和right都是移动过的(left比合格的palindrome-1,right + 1)所以正常length应该是right -left+1,在这里变成right -left-1。从中间往两边check,可以做到O(n^2)。expand palindrome这里太妙了。分odd和even两种情况。

2023-08-03 01:42:09 203

原创 LeetCode | dp | 322. Coin Change 300. Longest Increasing Subsequence 120. Triangle

从前往后,dp[i]是截止到i最多需要几个硬币。dp[i] = min(dp[i], dp[i - coins[0]] + 1, dp[i - coins[1] + 1...)从后往前,找的是从i开始有几个sequence。i的sequence数量是max(1,1+dp[i+1], 1+dp[i+2]...)。可以从上往下,但从下往上更好。可以避免两边界限地方设置MAX_INT,还可以直接return[0][0]

2023-08-02 18:04:48 47

原创 Leetcode | DP | 338. 198. 139.

从i==1开始,dp的array如果i是2的1次方之前的数,是1 + dp[i - 2 ^ 0];如果抢2,那么就要抢2和到0为止最多的钱;如果不抢2,那么就要抢到1为止最多的钱。如果抢3,那么就要抢3和到1为止最多的钱;如果不抢3,那么就要抢到2为止最多的钱。如果抢4,那么就要抢4和到2为止最多的钱;如果不抢4,那么就要抢到3为止最多的钱。如果i是2的2次方之前的数,是1 + dp[i - 2 ^ 1];如果i是2的3次方之前的数,是1 + dp[i - 2 ^ 2];

2023-08-01 02:10:06 380

原创 LeetCode|DP|70. 118. 119.

节省空间版的118.只需要两个vec,一个是老的,把老的后面push一个1,然后用新的算。2d array的熟练程度。

2023-07-31 11:46:17 434

原创 Leetcode | Kadane Algo | 53. 918.

可以在算第一种max的时候同时找到正常区间内的minsum。求一个total然后total减正常区间的minsum就是不正常区间的maxsum。如果cur_sum大于零,可以晋级到下一个元素,因为正数只会让之后的和更大。如果cursum小于零,那就把他reset成0,让下一个元素从头开始。全是负数的时候total减minsum会是0,大于最大的那个负数。按照正常的区间,不circular,就是53的思路即可。可以得到一个正常区间内的max。还有一个不正常的区间,circular,也会有一个max。

2023-07-30 23:06:40 420

原创 Leetcode | Binary search | 22. 74. 162. 33. 34. 153.

比如mid-1不valid的情况,就要看mid+1是不是大于mid,如果是的话就废了,如果不是就是peak(当然本题不会出现废了的情况,因为一定有peak)单增/单减的话,比middle大的那边是有可能有peak的,因为如果增大再在某处减小,就有peak,如果一直增大,那么在起头/结尾的地方会有peak因为 nums[-1] = nums[n] = -∞。如果存在,那么检查target的lowerbound是不是target,如果不是,-1,-1。先比较start和mid,判断mid落在左边还是右边。

2023-07-30 19:40:37 407

原创 LeetCode|backtracking|review:40. 131. 93. 47. 332. | 37. Sudoku Solver

(因为combination和子集问题i从start开始,permutation的i从0开始)(包括有序sequence,也是需要按照顺序 i = start一点一点往后看的)return false的地方:某一个方案一直往下填充,到后面发现没有符合条件的数字了,就只能return false,在上一层试另一种选择。已经有1,1,2,3了不需要第二个1,1,2,3。[1,1,2,3]中,答案里有[1,1,2], 但是不能有两个[1,2,3]已经有1,1,2了,进到第四层,不再去看2了。

2023-07-28 15:39:42 210

原创 LeetCode | Heap | 373. Find K Pairs with Smallest Sums, 295. Find Median from Data Stream

更好的方法(log(klogn)):先把nums1里所有的东西和nums2[0]的值结合,每次找到并且pop出一个和(index【i,j】,j最开始都是0),就把【i,j+1】的和push进去。最暴力的做法:直接算出每一对的和,并且用 pair记录nums1和nums2里哪两个idx。注意pq空了和nums2的index大于nums2的size的情况。这种找前k个最大/最小的题,直接上pq.

2023-07-26 09:57:33 50

原创 LeetCode | Heap | 502.

答题:这道题需要排序,又需要相对快速的push和pop。vector搭配sort每次插入都是logN。又不能直接hash map,因为没有排序。想要又有排序又有快速插入还可以用multimap。两种筛选方法:把capital符合要求的排个序,找profit最大的。按照profit排序,从大到小找capital满足条件的。一共两个变量:profit和capital。profit要求是找最大的。capital要求小于w。因为w只会增加,所以可以一直从capital的pq往profit的pq里push。

2023-07-24 17:48:51 111

原创 LeetCode | Bit Manipulation, heap | 190. 191. 136. 137. 201.215.

很重要的观察:在一段区间内,前n个数字会是一样的,后m个数字会不一样,而这m个数字里一定有0,which means &出来都是0.XOR的点在于,两个一样的数字a^a,结果是0. 且XOR是可以换位置的,所以把所有东西XOR在一起,剩下的就是单呗的。如果是max heap,那么从pq的constructor直接把所有元素放进去,pop(k-1)次,剩下的就是第k大的。如果是minheap,那么一个一个往里放,遇到size大于k就pop,最后剩下的顶上的就是第n大的。

2023-07-21 18:33:09 72

原创 LeetCode | Bit Manipulation | 67. Add Binary

小技巧:留在原地的是carry%2,进到下一位的carry是carry/2。while里的num--不要和 || 一起用,因为只会执行第一个--。注意carry == 1的情况。

2023-07-21 10:59:57 49

原创 Leetcode | binary tree general | 100. 117. 114. 129

这道题的终止条件不能是root == NULL。因为【1,2】这种当遍历到1右边的null时,sum==1,但是并不是到达了子叶节点。要判断子叶节点还是用left == null && right == null。可以用size也可以用NULL。NULL更精妙一点,但是逻辑是一样的。后序遍历,以及找到left链尾部链接之前right头的地方。需要一个工具用来do level seperation。和112一个思路,不能用null终止。

2023-07-20 17:26:17 52

原创 leetcode|math|9.172.69.50.

就是要找166乘到1一共有几个5。5,10,15,25...都算。166/5就是算一共有几个5。但是25其实贡献了两个5.所以166/25就是出现了几个25.每一个25都是在5的基础上多加了一个5。因为如果middle平方大于x,那么x/middle不round down也小于middle,而rounddown就更小于x了。如果一个一个乘,那么会overflow。这道题比较重要的是res的设置,每次res都更新为最近的平方。所以把x*x*x*x 分成x*x 和 x*x,再相乘。to_string 就行。

2023-07-16 18:50:42 456

原创 List合集|2.21.138.92. 82.61.86.146.

这里的重点在于,应该先放到前面,因为想要加入list只需要一个key就够。给一对值,如果map里已经存在,更新值,且list放到前面。而移到最前面这件事,要是想要快速,那么就需要这个key对应的list里node的地址。如果key存在,需要两个动作:1. 将list里key的那个node移到最前面。分成两个list,前面的list最后一个值接第二个list,注意后面的list最后一个值接NULL。细节:最后一位l1和l2都是null的时候,如果carry是1,那还要再加一个1。注意k%size才是真的k。

2023-07-16 16:16:50 213

原创 LeetCode|Stack|Review:20. 150. New:71. Simplify Path155. Min Stack 141. Linked List Cycle

这里相等是也要push,因为如果是一个个push 1,0,0,0,3,4,pop掉inde==2的零后,最小值还是0,如果等于时不push,最小值会变成1。20.注意三种情况:左括号多了,右括号多了,括号不match;需要用empty()判断。绕圈,fast和slow就行。fast==slow的判断可以放到while的主体里面。注意“..”的时候要返回之前的dir,也就是说要pop一下。一个stack正常操作,一个stack只记录越来越小的。150.注意左右别减反了就行。

2023-07-13 13:56:00 43

原创 LeetCode | Intervals binarytree| 228. Summary Ranges 57. Insert Interval 637. Average of Levels in B

注意start和end只需要和每个vec的结尾/开头对比就行。连续用“nums[i] == nums[i - 1] + 1”表示。注意forloop结尾收不好的情况‘很正常的level traverse。注意i超越边界的限制条件。

2023-07-12 13:04:14 44

原创 LeetCode|Hashmap|49. Group Anagrams 128. Longest Consecutive Sequence 219. Contains Duplicate II

因为是要记录连续的数字,而且num的范围太大不能用vector,用map先存好,然后直接判断map[i] + count是否存在来判断连续的长度。可以先排除map[i] - 1的数字为开头,剪一下枝。值做key,index做val,遇到一样的值比较index,要么return true,要么更新index。利用index有序。记得用auto和second。

2023-07-11 12:11:46 43

原创 LeetCode|Matrix | 36. Valid Sudoku 48. Rotate Image 73. Set Matrix Zeroes 289. Game of Life

如果记录本列/行是0,那么第一行/列的数字无所谓,直接变0就行,如果不是0,那么第一行的值保留。因为给了passer by reference的param且是int,我们可以增加刚死和刚活两个选项:既记录了本轮之前谁是死的谁是活的,用于其他格子的计算,又可以记录本次本格子是死是活。注意把第一行/列标记为0的行列都设置成0的时候,只需要再loop一遍全局就行,不用一个for套一个if再套一个for。用一个array[m]一个array[n]分别记录哪行哪列应该是0,SC是O(m+n)

2023-07-10 16:56:56 34

原创 LeetCode|Sliding Window,hash|3. 无重复字符的最长子串 205. Isomorphic Strings 290. Word Pattern

start的实现方式:因为每次遇到一样字母都会更新最新的index,所以start更新后一定是最近的重复了的字母(abab中a和b都有重复,start到第二个b的时候一定更新到3,因为b是最近重复的,也就是window里重复了的)这道题点在于不仅t里的两个字母不能对应s里的一个字母,s里的两个字母也不能对应t里的同一个字母。所以如果是循环s去对应t的话,只能保证s里的a不对应t里的b和c。所以还需要再t循环一次。start增加的情况:当前字母和window里的有重合,start变成当前字母。

2023-07-07 16:07:17 38

原创 LeetCode|Array 2pointers|6. Zigzag Conversion 392. 判断子序列 167. 两数之和 II - 输入有序数组

经典twosum是没有排序过的,这个给你排好了,直接2pointer,就别hash了。但其实根本不需要考虑col,反正最后也是一排一排输出,col无所谓。复习nested vector 的initialization。记得edgecase numRows==1的情况。两个pointer各跟踪一个string。

2023-07-04 22:09:30 64

原创 LeetCode|Divide and Conquer|427. Construct QuadTree 125. Valid Palindrome 28. Find the Index of the

注意这种情况: if(needle.size() > haystack.size()) return -1;不想学kmp,先bruteforce吧。正常回溯,拆分,但是找不到bug。

2023-07-04 00:58:15 28

原创 LeetCode|Divide and Conquer,Array|148. Sort List 28. Find the Index of the F 58. Length of Last Word

本质就是merge sort,复杂度时间是O(nlogn),因为一共回溯了logn次并且每次里面都要重新排序,故每次都要花n的时间。空间是O(logn),因为一共回溯logn次且每次都要占用O(1)的空间(cur,left,right啥的)因为是linkedlist所以其实哪怕是排序也用的是老地址,没有每次都增加新的O(n)。哪怕是这种情况,也只能是aa,index到不了b,因为如果想要aab,那么第一个会变成aaba,那么aab就会排在前面。一个难点是找中点,也就是快慢指针方法。

2023-07-03 21:45:48 21

原创 LeetCode|Array|238. Product of Array Except Self 12. Integer to Roman 169. Majority Element

如果把prefix存在res的vec里,然后再用一个循环算postfix然后乘以在res里面的prefix,就可以用O(1)的空间复杂度。每次分别找到左和右的最大次数值,如果相等就返回,如果不相等就左+右整体找一下到底哪个是最大次数。纯笨题两种方法:1)全写出来 2)除了1,4,5,9,10...都写出来。divide and conquer 很久没写过了,今天预习一下,明天写d&c的主题。找次数可以用count(nums.begin(), nums.end(), 1);

2023-07-01 19:06:08 31

原创 LeetCode|Array|274. H-Index 121. Best Time to Buy and Sell Stock 380. Insert Delete GetRandom O(1)

O(n)的提示:可以找到循环到i为止的最小值,而nums[i]-最小值一定是目前这个i所能达到的最大profit。其次这道题的要点在于用了map可以解决O(1)插入删除,但getrandom需要在vector里进行,每次map变动vector也要变动过,而vector没有快速的删除。解决办法:map的val用来储存在vec中的位置。注意一个细节:实现remove的时候,vec.back()在map里的val要变(位置变化)sort一下然后O(nlogn)复杂度的方法挺好写的。首先注意rand()的应用。

2023-06-30 14:50:53 25

原创 LeetCode|Array|88. Merge Sorted Array 189. Rotate Array 80. Remove Duplicates from Sorted Array II

快慢指针,和基础版思路一致。只不过这次要比较的范围变长了,导致如果遇到“1112234”,会变成“1122234”,误认222。所以记录prev和prev_prev吧!普通双指针写法,思路正确。把index1/2 < 0的情况写在括号里用 || 分割会有奇怪的bug,没de出来,先跳过。rotate老问题了,用reverse就行。注意这里k可以大于size,要取一个%,可以用end-k。三道题都不难,思路比较清晰,是之前做的基础题的变体,小细节和读题问题多试几次也能试出来。

2023-06-29 16:39:21 57

原创 代码随想录算法训练营第二十三天| 669. 修剪二叉搜索树 108.将有序数组转换为二叉搜索树 538.把二叉搜索树转换为累加树

这道题不需要返回值因为不需要记录左边是什么右边是什么,然后再两个东西相加什么的。这道题把握右中左的原则,用一个sum一路记录累加的和,然后赋值就可以。这道题不是只找一个节点或者一条path找到了就return,所以矫正之后不能直接return。和删除节点不一样,删除节点属于找到目标节点了之后删除,处理,然后直接return,返回上一层直接接上。这个是看到一个节点处理一个节点。确定了之后在单层递归逻辑里,left = traverse(left),right = traverse(right)就行。

2023-06-28 23:17:47 23

原创 代码随想录算法训练营第二十二天| 235. 二叉搜索树的最近公共祖先 701.二叉搜索树中的插入操作 450.删除二叉搜索树中的节点

分情况讨论,这些情况的删除都在终止条件里, which means 终止条件return的应该是新的已经删除好的node。而单层递归逻辑里面直接left = traverse(left),right = traverse(right)就行。key observation: bst的最近公共祖先一定是从上往下遍历遇到的第一个pq区间内的数字。要删除的节点两边都有node的情况下,把左子树放在右子树的left most node下面就行。明白这个思路就好写了。c++记得delete。不难 加到下面就行了。

2023-06-28 17:35:28 18

原创 代码随想录算法训练营第二十一天| 530.二叉搜索树的最小绝对差 501.二叉搜索树中的众数 236. 二叉树的最近公共祖先

如果root是null,只好return null,如果是left或right,return本身。如果left有right没有,返回left(left要么是pq,要么是已经求出来的最小祖先),left没有right有同理。如果left right都没有,那么就return null好了,因为本身如果是pq的情况最开始已经讨论过了。所以可以边遍历变记录。如果是随便一个二叉树,把次数放到map的value里,把map转化为vector,然后对vector排序,就能找到最大频率的众数们。

2023-06-26 17:30:01 31

原创 代码随想录算法训练营第二十天| 654.最大二叉树 617.合并二叉树 700.二叉搜索树中的搜索 98.验证二叉搜索树

层序遍历,bfs,用queue,只是这里不需要用queue,直接按照直觉左右左右就行,但其本质是层序遍历,只不过因为只有两个子节点且明确方向罢了。陷阱:只比较局部root和其left、right的合法性,但其实最右的node不仅要大于自己的root,还要大于最上面的root。需要用max记录,max不能初始化为INT_MIN因为最小的node有可能是INT_MIN这样就没办法只保证大于max了。即使是用回溯,也是用中序遍历看是否一直增大。int的最小值 = -2^31。构造二叉树,一次过,不太难。

2023-06-26 14:58:38 70

原创 代码随想录算法训练营第十三天| 239. 滑动窗口最大值 347.前 K 个高频元素 总结

如果front和消失的值一样就pop,不一样不用管,因为原序列中最大的才会在front,如果消失的是小一点的值,已经在大值被放到deque里的时候去掉了。pq排序的过程的时间复杂度是O(log k) 每次插入都是往size为k的heap里插入一个值,整个算法的时间复杂度是O(nlog k)declare type的时候尖括号里面的也需要是type。从map到pq的这部分,注意iterator的写法。前k个的问题都可以用heap。滑动的方法:先加入k个元素进入range,然后i从k遍历到结尾。

2023-06-25 18:16:45 24

原创 代码随想录算法训练营第十一天| 20. 有效的括号 1047. 删除字符串中的所有相邻重复项 150. 逆波兰表达式求值

注意前括号和后括号剩余的情况(前者通过stack里有无剩余括号确定,后者会在stack空了没有top的情况出现)注意注释标记的地方。stoi很好用,把string转换成int。为了安全也可以stol/stoll。比较简单,遇到bracket才push进stack。如果没有符号只有一个数字那么直接返回就行。

2023-06-25 11:36:47 77

原创 代码随想录算法训练营第十天| 理论基础 232.用栈实现队列 225. 用队列实现栈

pop四步走:pop&存que里的入que1,只留一个;把这一个记录然后pop,不放入que1;que = que1;清空que1(没有clear的操作,只能while not empty)蛮简单的,一个in_stack一个out_stack,push就往in里放,pop就从out放就行。out如果是空的就把in里的都放进去。queue是有back()的!return top直接return que.back()就行。queue之间可以随意赋值。

2023-06-24 18:55:45 210

原创 代码随想录算法训练营第九天| 28. 实现 strStr() 459.重复的子字符串 字符串总结 双指针回顾

删除替换填充都可以用双指针,fast是for loop里的i。反转相关:局部反转然后整体反转可以解决旋转和单词反转的题。

2023-06-24 17:10:57 88

原创 代码随想录算法训练营第八天| 344.反转字符串 541. 反转字符串II 剑指Offer 05.替换空格 151.翻转字符串里的单词 剑指Offer58-II.左旋转字符串

这题有病,如果可以有额外空间跟简单,没有就先reverse前半段,然后再reverse后半段,然后再整体revrse。reverse的写法:reverse(s.begin(), s.begin() + 3),左闭右开。去除空格很麻烦,最开始的空格,最后的单个空格都要考虑。反转字符的题i的条件小于size/2就行,卡在中间之前,正好。先算出最终的size,然后从后往前双指针。

2023-06-24 16:59:27 151

原创 代码随想录算法训练营第四天| 24. 两两交换链表中的节点 19.删除链表的倒数第N个节点 面试题 02.07. 链表相交 142.环形链表II 总结

注意这道题swap的技巧,保证永远是b链更长,标准,好写。一步一步更新就行,发现乱了的地方直接设置temp储存。设置dummy,且记得是要删除第n个。这种涉及头节点的都设置dummy。

2023-06-22 11:28:57 19

原创 代码随想录算法训练营第三天| 链表理论基础 203.移除链表元素 707.设计链表 206.反转链表

必须用size推算出back而不能直接设置一个back = NULL因为addatback的时候你不能back->next = new, 因为back可能是null。返回要返回prev,因为prev是本轮的cur,而本轮的cur是最后一个非NULL的pointer。按照自己的逻辑写,while里面不用判断cur->next,因为即使是null也无所谓。最后记得delete dummy head,while里面是cur->next。用dummyhead会比较方便。203.移除链表元素。struct 加分号。

2023-06-19 20:36:09 127

原创 代码随想录算法训练营第十八天| 513.找左下角值112. 路径总和113.路径总和ii236. 二叉树的最近公共祖先106.从中序与后序遍历序列构造二叉树105.从前序与中序遍历序列构造二叉树

其次不能是bool,因为最近公共祖先会通过收到left和right回溯出来都是true而被找出来,而找到了还是要返回true。可以,但是会很难看。答案的方法很简洁,终止条件里只会return p/q/NULL,处理本层逻辑里并不纠结谁满足了p谁满足了q,只要不是null,那么就返回不是null的东西,如果两边都不是null,直接返回root,如果一边有null,就返回非null的一边。这道题值得思考的是是否需要返回值,我们并不需要处理任何递归回来的东西,所以void就行。前中后序和回溯是什么关系?

2023-06-19 18:45:23 19

空空如也

空空如也

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

TA关注的人

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