自定义博客皮肤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)
  • 收藏
  • 关注

原创 专题:前缀和(Prefix Sum)模式

什么是前缀和数组?定义为:有 N 个的正整数放到数组 A 里,现在要求一个新的数组 B,新数组的第 i 个数 B[i]是原数组 A 第 0 到第 i 个数的和。这样的数组B我们就把它称为A的前缀和数组。前缀和是一种重要的预处理,能大大降低查询的时间复杂度。我们可以简单理解为“数列的前 n 项的和”。这个概念其实很容易理解,即一个数组中,第 n 位存储的是数组前 n 个数字的和。对 [1,2,3,4,5,6] 来说,其前缀和可以是 pre=[1,3,6,10,15,21]。我们可以使用公式 pre

2021-10-27 16:08:20 593

原创 二叉树递归解法(Recursion)模式总结

Leetcode中的递归的问题总是很头疼,特别对于二叉树问题,因为二叉树是左右子树的形式,天生就具有递归性。在这篇文章中,系统总结一套解决递归问题的模版思路与解法,以后使用这个思路可以秒解很多二叉树的递归问题。递归解题三部曲何为递归?程序反复调用自身即是递归。我自己在刚开始解决递归问题的时候,总是会去纠结这一层函数做了什么,它调用自身后的下一层函数又做了什么…然后就会觉得实现一个递归解法十分复杂,根本就无从下手。相信很多初学者和我一样,这是一个思维误区,一定要走出来。既然递归是一个反复调用自

2021-09-03 11:02:27 390

原创 动态规划(Dynamic Programming)模式(4. 双序列型)

双序列型,顾名思义,就是有两个序列/字符串,需要进行一些操作。每个序列是一维的。可以转化成二维的动态规划。经典题1:https://leetcode.com/problems/longest-common-subsequence/这样我们从最后一步考虑起,最后一个字符,它是否在最长公共子串中。代码如下:public int longestCommonSubsequence(String text1, String text2) { int l

2021-08-22 11:36:57 406

原创 动态规划(Dynamic Programming)模式(3. 划分型)

划分型的动态规划,给定长度为N的序列或字符串,要求划分成若干段。段数不限,或指定K段 每一段满足一定的性质做法:类似于序列型动态规划,但是通常要加上段数信息; 一般用dp[i][j]记录前i个元素,分成J段的性质,如最小代价https://leetcode.com/problems/perfect-squares/还是从最后一步思考:得到的状态转移方程如下:代码如下:public int numSquares(int n) { .

2021-08-20 10:03:52 223

原创 动态规划(Dynamic Programming)模式(2. 序列状态型)

序列型和坐标型的最大区别是序列型不是简单的用坐标表示DP值,而一般需要加上状态。https://leetcode.com/problems/house-robber/按照解决DP问题的一般情况来,我们先分析最后一步。最后一步的最优策略中,有可能偷,也可能不偷最后一栋房。那么为了方便计算,一般我们可以考虑在dp中加入一个状态。所以这个问题可以简化为是否偷I – 1套房子。那么我们可以将DP定义简化:代码就很简单了:public int rob(int[] nums)

2021-08-19 18:08:04 106

原创 专题:动态规划(Dynamic Programming)模式(1. 坐标型)

动态规划(Dynamic programming,简称DP)是一种在数学、管理科学、计算机科学、经济学和生物信息学中使用的,通过把原问题分解为相对简单的子问题的方式求解复杂问题的方法。 动态规划类的题目在leetcode中是一大类,可以使用DP求解的问题一般有如下几个特点:计数1.1)有多少种方式跳到右侧,多少种方式走到右下角 1.2)有多少种方法选出K个数使得和是Sum 2) 求最大值和最小值...

2021-08-18 12:00:16 203

原创 专题:拓扑排序(Topological sort)模式

拓扑排序用于查找相互依赖的元素的线性排序。例如,如果事件“B”依赖于事件“A”,则“A”按拓扑顺序排在“B”之前。该模式定义了一种简单的方法来理解对一组元素执行拓扑排序的技术。该模式的工作方式如下:初始化a) 使用 HashMap(或List数组)将图存储在邻接列表中;b) 使用 HashMap 来构建邻接表, 计算所有节点的入度c) 将所有入度为0的顶点都将作为源并存储在队列queue中。a) 对于每个源,执行以下操作:-i) 将其添加到排序列表中。— ii) 从图

2021-08-03 17:36:37 311

原创 专题:0/1背包问题(0/1 Knapsack)模式

背包问题是一类经典的动态规划问题,它非常灵活,需要仔细琢磨体会,本文对背包问题中基本的0/1背包问题和对应的leetcode题目作一个总结,期望可以用一套框架解决背包问题。01 背包问题:最基本的背包问题就是 01 背包问题:背包承重为 Capacity, 现在有n个物品,物品重量 w[n], 物品价值 v[n]。如何选择物品价值最大?特点:每种物品仅有一件,可以选择放或不放, 即0/1.1.1 背包问题具备的特征:是否可以根据一个 target(直接给出或间接求出),target 可以是

2021-08-01 11:26:56 693

原创 专题:多路归并(K-way merge)模式

多路归并可以帮助解决涉及一组排序数组的问题。每当获得“K”个排序数组时,都可以使用堆(Heap)高效地对所有数组的所有元素执行排序遍历。您可以在最小堆中推送每个数组的最小元素以获得整体最小值。获得整体最小值后,将同一数组中的下一个元素推送到堆中。然后,重复此过程以对所有元素进行排序遍历。图示如下:多路归并三个list该模式通用算法如下所示:在最小堆中插入每个数组的第一个元素。 从堆中取出最小(顶部)元素并将其添加到合并列表中。 从堆中移除最小元素后,将同一列表的下一个元素插入

2021-07-21 17:26:47 3173

翻译 专题:Top K元素(Top K elements)模式

当看到从一个集合中寻找最大/最小/最频繁的Top K个元素时,可以套用这个模式。解决Top K问题的最好数据结构是堆(Heap)。这个模式也是使用大根堆/小根堆去解决Top K问题,流程如下:插入K个元素到小根堆/大根堆中; 遍历剩下的元素,如果发现小于/或者大于堆中的元素,则将堆层的元素出队列,然后插入该元素。 最后留下的即为符合要求的元素。从[3, 1, 5,12,2,11]中找到最大的3个元素的流程图如下:如何识别符合这个模板的问题:从一个给定集合中寻找最大/最小/最频繁

2021-07-16 16:53:41 263

原创 高频刷题-最大最小堆(Two heaps)专题

有许多问题是关于一组元素,可以把他们分成两个部分。为了解决问题,我们会对前半部分元素的最小的元素、另一半元素的最大的一部分感兴趣。Two heaps模式就是一种有效解决这样的问题的方法。Two heaps使用了两个堆:一个最小堆找到最小的元素,最大堆找到最大的元素。我们存储前半部分元素到最大堆种,后半部分元素到最小堆种。这样,如果我们需要计算中位数,直接可以根据这两个堆的堆顶元素就可以计算出来。Two heaps模式适用于如下场景:在Priority Queue, 日程安排(Scheduling

2021-07-15 12:12:32 253 1

原创 高频刷题-二叉树深度优先搜索(Depth First Search)专题

下面我们介绍DFS遍历算法。这个算法在解决需要遍历树的问题时非常有效。不同于广度优先遍历算法,DFS是一头遍历到节点节点,因此需要保存每次遍历的父节点的信息。通常我们是使用递归的方式进行遍历,也可以采用statck去保存。从特点可以看出,DFS的空间复杂度和递归的深度有关,是O(H),H是树的最大深度。每个节点都会遍历一次,时间复杂度也是O(N). N为节点数。下面我们还是直接看题目:https://leetcode.com/problems/path-sum/计算二叉树的路径和

2021-07-12 17:24:07 203

原创 高频刷题-二叉树广度优先搜索(Breath First Search)专题

今天我们介绍二叉树的BFS和DFS。以前二叉树专题的时候已经使用BFS和DFS算法去解决过二叉树的相关问题。这次我们再总结一下BFS和DFS算法的特点和模板。因为BFS算法的特点,在解决二叉树按层级遍历问题时非常有用。我们将使用一个队列(Queue)来跟踪的所有节点级别之前我们跳到下一个级别。这也意味着,算法的空间复杂度是O (N),其中N是节点在每一层级的最大数量。 下面我们直接看题目:https://leetcode.com/problems/binary-tree-le...

2021-07-11 12:24:24 207 1

原创 高频刷题-就地反转链表(In-place Reversal of a Linked List)专题

这次我们将介绍就地反转一个链表的模板,这个模板解决涉及逆转一个链表的时候非常有用,我们可以做到不使用额外的内存,在时间复杂度为O(n)的情况下完成。该文参考如下博客:https://emre.me/coding-patterns/in-place-reversal-of-a-linked-list/我们直接看这个题目:https://leetcode.com/problems/reverse-linked-list/首先我们介绍iteration方法,这是一种遍历整个链表结构的方法.

2021-07-08 11:52:17 192 1

原创 高频刷题-Interval相关问题专题

该博文参考了如下blog:https://emre.me/coding-patterns/merge-intervals/https://leetcode.com/discuss/general-discussion/794725/General-Pattern-for-greedy-approach-for-Interval-based-problems/658450Interval中文意思是间隔,可以理解为区间。生活中很多可以描述为interval,例如会议时间的区间,公交车运行站点区间等等

2021-07-06 09:57:55 427 1

原创 高频刷题-循环排序(Cyclic Sort)专题

参考如下链接:https://emre.me/coding-patterns/cyclic-sort/以前的文章我们介绍了滑动窗口(Sliding Window), 双指针(Two Pointers), 快慢指针(Fast & Slow Pointers)等模板。今天,我们介绍一种新的解题模板,称为循环排序(Cyclic sort或Cycle sort)。这是一种非常有用的解决这种数组:包含的数字在给定数组的长度范围内,寻找缺失或重复的数字问题的方法。下面图示下:对于数组[2,

2021-07-02 16:11:39 736 1

原创 高频刷题-双指针法(two-pointers)专题

双指针法是一个可以是一个算法模板,经常被运用在有序的数组或列表中。和滑动窗口不同的是,此时的双指针是从两侧到中间,通俗点也可以称为夹逼法。例如,从一个有序数组中找到符合一定条件的元素组。直接遍历整个集合,需要进行O(n^2)或者O(n^3)复杂度的遍历。而双指针的夹逼法,通常可以只遍历一次即可找到结果,有效的节省了时间复杂度和空间复杂度。确定何时使用双指针方法的方法:它将处理排序数组(或链表)并需要找到一组满足某些约束的元素的问题数组中的元素集是一对、三元组,甚至是子数组。...

2021-06-28 16:12:25 205

原创 高频刷题-滑动窗口(Sliding Window)专题

滑动窗口算法多用于处理数组(Array), 字符串(String)或者链表(LinkedList)中关于子字符串(Substrings), 子数组(Subarrays, Sublists)等连续问题。该算法可以将多重嵌套的循环转化为单循环,从而降低时间复杂度(O(n))。滑动窗口是同向双指针的一个类型。注意上述的滑动窗口示意图是固定大小,而现实中窗口大小也可以是不固定的。下面给出滑动窗口算法的一个模板,来源于leetcode并做了一些理解上的修改。注意模板给出的是一个非固定大小...

2021-06-25 16:19:14 413 1

原创 高频刷题-74. Search a 2D Matrix

https://leetcode.com/problems/search-a-2d-matrix/这个题目看得出来matrix从头到尾就是一个排序的集合,所以二分查找是必然的。唯一要做的处理就是每次换行的时候怎么进行跳转。每次我们计算了中间值后,可以从中间数算出对应的matrix的长和宽: Matrix 长 = mid / column; Matrix 宽 = mid % column;这样这个题目直接套用二分查找的模板就可以了,这里我们采...

2021-06-21 11:59:30 104

原创 高频刷题-二分查找(Binary Search)专题

leecode 中有很多binary search的题。一般而言,当一个题目出现以下特性时,你就应该立即联想到它可能需要使用二分查找:待查找的数组有序或者部分有序 要求时间复杂度低于O(n),或者直接要求时间复杂度为O(log n)二叉搜索的思想很好理解,但是其中的边界条件却很繁琐,很多时候写出来的代码不能很好的处理边界条件。例如:同时,二叉搜索有很多的变体,例如:对于这些条件和边界的总结,qq下面这篇文章可以说彻底的让你理解清楚。https://leetcode-cn.c.

2021-06-18 17:59:54 216

原创 高频刷题-8. String to Integer (atoi)

https://leetcode.com/problems/string-to-integer-atoi/这个题实现String to Integer的转换,规则较多,没太多的算法层面的东西,就是按照题目的规则去实现就行了。要注意有很多corner case,需要有很多的判断。实现代码和注释如下:...

2021-06-17 10:50:11 69

原创 高频刷题-69. Sqrt(x)

https://leetcode.com/problems/sqrtx/本题的暴力解法是从1到x分别求平方,找到第一个小于等于x的数即可。这样的线性解法时间复杂度为x,如果x非常大的话,效率会很低。因此这类题目需要考虑使用二分查找,查看1和x的中间数mid的平方n,如果n等于x,那么返回mid。如果n小于x并且mid加一的平方大于x,这时也可以返回mid。除此之外,如果n小于x,左指针变为mid加一,反之右指针变为mid-1。实现代码如下:public int mySqrt(int x) ..

2021-06-15 12:24:34 421

原创 高频刷题-151. Reverse Words in a String

https://leetcode.com/problems/reverse-words-in-a-string/翻转字符串中的每一个单词,因为要翻转每一个单词,首先想到的是根据“ ”去分割字符串得到单词,然后入栈,再出栈。利用栈的LIFO的特性达到翻转的目的。这样就来了解法1:public String reverseWords(String s) { Stack<String> st = new Stack<String>(); ..

2021-06-15 12:08:24 102

原创 高频刷题-42. Trapping Rain Water

https://leetcode.com/problems/trapping-rain-water/这个问题我们采用的算法是全局遍历,找到最高点所在的index,然后对于左侧和右侧,分别计算蓄水量。对于左侧,蓄水量为左侧最大高度 – 当前高度,然后将蓄水量相加;右侧也是一样,从右向左遍历,蓄水量为右侧最大高度 – 当前高度。最后结果是左右之和。具体看代码,加了注释,很容易看懂。...

2021-06-15 12:06:51 93

原创 高频刷题-33. Search in Rotated Sorted Array

https://leetcode.com/problems/search-in-rotated-sorted-array/最开始想到的是找到rotation的位置pos,然后对前和后的sorted array分别进行二分查找。可惜这种方法找到pos的位置的时间复杂度是o(n),不符合要求。只有使用二分法才能达到题目要求的O(logN)的时间复杂度。考虑到一个rotation之后的array,找到mid,则对于mid分成的三部分,即为start , mid , end. 必然有一部分为排...

2021-06-09 18:02:20 87

原创 高频刷题-5. Longest Palindromic Substring

https://leetcode.com/problems/longest-palindromic-substring/

2021-06-06 16:59:59 173

原创 高频刷题-110. Balanced Binary Tree

https://leetcode.com/problems/balanced-binary-tree/由于平衡二叉树的定义,很容易想到这题是计算树的最大深度的扩展。思路1:计算节点的左子树和右子树的最大深度,如果该节点的左右子树的深度超过1,则不是平衡二叉树;如果<=1,则需要再次递归遍历其后代节点;实现代码如下:...

2021-06-06 10:11:56 53

原创 高频刷题-207. Course Schedule和210. Course Schedule II

https://leetcode.com/problems/course-schedule/拓扑排序用于解决有向无环图(DAG, Directed Acyclic Graph)按依赖关系排线性序列问题,直白地说解决这样的问题:有一组数据,其中一些数据依赖其他,问能否按依赖关系排序(被依赖的排在前面),或给出排序结果。最常用解决拓扑排序问题的方法是Kahn算法,步骤可以概括为:根据依赖关系,构建邻接矩阵或邻接表、入度数组; 取入度为0的数据(即不依赖其他数据的数据),根据邻...

2021-06-03 15:53:29 122

原创 高频刷题-54. Spiral Matrix

https://leetcode.com/problems/spiral-matrix/解决方法很简单,由顶、右、底、左外边界逐步向里遍历矩阵,将元素置入结果矩阵返回即可。

2021-06-01 12:18:50 85

原创 高频刷题-232. Implement Queue using Stacks

https://leetcode.com/problems/implement-queue-using-stacks/用两个stack(LIFO)去实现队列(FIFO), 这两种结构是完全相反的,所以需要一个辅助的stack将入栈的数据给倒置以下,最先想到的办法是实现push,首先导致当前栈stack的元素到back栈中,然后push当前的元素,再从back中导入回来:这样使得pop(), peek都非常简单。实现代码如下:class MyQueue { priva...

2021-05-30 15:39:42 87

原创 高频刷题-64. Minimum Path Sum

https://leetcode.com/problems/minimum-path-sum/该题看到题目,计算最小值,第一反应就是dp解法.对于不是第0行或者第0列的grid,有两种方法到[m][n],即为上方到达,或者左边到达,因此dp[m][n]等于上面两种方法的最小dp,加上当前节点的值。但是对于第一行和第一列则就是前面的dp加上当前节点的值。推导出的dp公式为:dp[m][n] :对于m == 0, dp[0][n] = dp[0][n - 1] + grid[0][n];..

2021-05-30 11:24:16 90

原创 高频刷题-200. Number of Islands

该题想法很简单,我们只需要遍历整个二维数组,然后遇到 1 的时候,把当前的 1 以及它周围的所有 1 都标记成一个字符(此时标记成0,可以理解为找到该岛的全部区域,然后把该岛沉下去)。然后记录遇到了几次 1,就代表有几个岛屿。看下边的例子:[1] 1 0 0 01 1 0 0 00 0 1 0 00 0 0 1 1当前遇到了 1, count = 1;把当前的 1 和它周围的 1 标记为 00 0 0 0 00 0 0 0 00 0 1 0 00 0 ...

2021-05-28 15:40:02 79

原创 高频刷题-回溯法(backtracking)专题

首先,什么是backTracking?这是backtracking和brute force的区别:Backtracking can be seen as an optimized way to brute force. Brute force approaches evaluate every possibility. In backtracking you stop evaluating a possibility as soon it breaks some constraint provide

2021-05-26 15:39:38 131

原创 高频刷题-104. Maximum Depth of Binary Tree

https://leetcode.com/problems/maximum-depth-of-binary-tree/两种方法,首先recursion。 很容易想到树每个节点的最大深度等于它左右子树深度最大值 + 1。 因此解法1就出来了:public int maxDepth(TreeNode root) { if (root == null) return 0; return Math.max(maxDepth(root.left), maxDepth(ro..

2021-05-23 11:33:09 62

原创 高频刷题-199. Binary Tree Right Side View

https://leetcode.com/problems/binary-tree-right-side-view/又是一道tree的题。还是两种方法,第一种递归(recursion),使用上面遍历树的模板。这道题其实就是优先找到右子树的节点,没有右子树则找到左子树,因此递归的时候需要带上层级level,另外,采用先右节点,再左节点的方式遍历该树,需要确保第一个节点(优先右节点,没有右节点则为左节点)被加入到最后的结果中。public List<Integer> rig...

2021-05-21 16:49:14 89

原创 高频刷题-704. Binary Search

https://leetcode.com/problems/binary-search/二分查找,没啥好说的,就是一个left,一个right,和一个pivot去判断当前的target是在哪个范围内。值得注意的是取平均数pivot = (left + right) / 2,这句如果left + right有可能会溢出(超过int所能表示的最大值)。那么可以改成left + (right - left) / 2,或者(left + right) >>> 1。至于left + (r..

2021-05-21 10:48:44 104

原创 高频刷题-94, 144, 145 二叉树的前序中序后序遍历

二叉树的preorder, inorder and postorder 遍历,在leetcode中都有对应的题。下面一起介绍,同时介绍recursion和iteration两种方式实现。https://leetcode.com/problems/binary-tree-inorder-traversal/https://leetcode.com/problems/binary-tree-preorder-traversal/https://leetcode.com/problems/bin.

2021-05-19 17:42:07 62

原创 高频刷题-236. Lowest Common Ancestor of a Binary Tree

https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-tree/该视频讲解非常清楚: https://www.bilibili.com/video/av587360571/总体思想是recursion,当root为null时,返回给null 当root的值等于p或者q时,返回这个root 先遍历左子树 再遍历右子树 当left,right均找到时返回此root 只找到left时返回left 只找到righ..

2021-05-17 17:14:21 54

原创 高频刷题-102. Binary Tree Level Order Traversal 和 103. Binary Tree Zigzag Level Order Traversal

https://leetcode.com/problems/binary-tree-level-order-traversal/对于二叉树,方法都是BFS和DFS两种。BFS,全称Breadth First Search,中文名为广度优先搜索。是一种以宽度方向搜索某种数据结构的一种方法,常用队列实现BFS算法。广度优先搜索并不是某一个固定的算法,它是一类符合上述所说的算法。BFS一般为按层级遍历,每一层级搜索完后再进入下一层级。DFS,全称Depth First Searc...

2021-05-16 17:06:24 77

原创 高频刷题-88. Merge Sorted Array

https://leetcode.com/problems/merge-sorted-arraymerge有序数组,由于两个数组都是有序的,所有只要按顺序比较大小即可。从 nums1 和 nums2 数组的末尾开始一个一个比较,把较大的数,按顺序从后往前加入merge之后的数组末尾。需要三个变量 i,j,k,分别指向 nums1,nums2,和merge数组的末尾。进行 while 循环,如果i和j都大于0,再看如果 nums1[i] > nums2[j],说明要先把 nums1...

2021-05-09 18:02:04 66

空空如也

空空如也

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

TA关注的人

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