<?xml version="1.0" encoding="utf-8" ?><rss version="2.0"><channel><title><![CDATA[wangpu_baggio的博客]]></title><description><![CDATA[]]></description><link>https://blog.youkuaiyun.com/wangpu_baggio</link><language>zh-cn</language><generator>https://blog.youkuaiyun.com/</generator><copyright><![CDATA[Copyright &copy; wangpu_baggio]]></copyright><item><title><![CDATA[专题：前缀和(Prefix Sum)模式]]></title><link>https://blog.youkuaiyun.com/wangpu_baggio/article/details/120995177</link><guid>https://blog.youkuaiyun.com/wangpu_baggio/article/details/120995177</guid><author>wangpu_baggio</author><pubDate>Wed, 27 Oct 2021 16:08:20 +0800</pubDate><description><![CDATA[什么是前缀和数组？定义为：有 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]]></description><category></category></item><item><title><![CDATA[二叉树递归解法(Recursion)模式总结]]></title><link>https://blog.youkuaiyun.com/wangpu_baggio/article/details/120077237</link><guid>https://blog.youkuaiyun.com/wangpu_baggio/article/details/120077237</guid><author>wangpu_baggio</author><pubDate>Fri, 03 Sep 2021 11:02:27 +0800</pubDate><description><![CDATA[Leetcode中的递归的问题总是很头疼，特别对于二叉树问题，因为二叉树是左右子树的形式，天生就具有递归性。在这篇文章中，系统总结一套解决递归问题的模版思路与解法，以后使用这个思路可以秒解很多二叉树的递归问题。

递归解题三部曲

何为递归？程序反复调用自身即是递归。

我自己在刚开始解决递归问题的时候，总是会去纠结这一层函数做了什么，它调用自身后的下一层函数又做了什么…然后就会觉得实现一个递归解法十分复杂，根本就无从下手。

相信很多初学者和我一样，这是一个思维误区，一定要走出来。既然递归是一个反复调用自]]></description><category></category></item><item><title><![CDATA[动态规划(Dynamic Programming)模式(4. 双序列型)]]></title><link>https://blog.youkuaiyun.com/wangpu_baggio/article/details/119850406</link><guid>https://blog.youkuaiyun.com/wangpu_baggio/article/details/119850406</guid><author>wangpu_baggio</author><pubDate>Sun, 22 Aug 2021 11:36:57 +0800</pubDate><description><![CDATA[双序列型，顾名思义，就是有两个序列/字符串，需要进行一些操作。

每个序列是一维的。

可以转化成二维的动态规划。



经典题1：



https://leetcode.com/problems/longest-common-subsequence/





这样我们从最后一步考虑起，最后一个字符，它是否在最长公共子串中。



代码如下：


public int longestCommonSubsequence(String text1, String text2) {
        int l]]></description><category></category></item><item><title><![CDATA[动态规划(Dynamic Programming)模式(3. 划分型)]]></title><link>https://blog.youkuaiyun.com/wangpu_baggio/article/details/119817047</link><guid>https://blog.youkuaiyun.com/wangpu_baggio/article/details/119817047</guid><author>wangpu_baggio</author><pubDate>Fri, 20 Aug 2021 10:03:52 +0800</pubDate><description><![CDATA[划分型的动态规划，给定长度为N的序列或字符串，要求划分成若干段。

段数不限，或指定K段
	每一段满足一定的性质


做法：

类似于序列型动态规划，但是通常要加上段数信息；
	一般用dp[i][j]记录前i个元素，分成J段的性质，如最小代价




https://leetcode.com/problems/perfect-squares/

还是从最后一步思考：



得到的状态转移方程如下：





代码如下：




public int numSquares(int n) {
        .]]></description><category></category></item><item><title><![CDATA[动态规划(Dynamic Programming)模式(2. 序列状态型)]]></title><link>https://blog.youkuaiyun.com/wangpu_baggio/article/details/119808125</link><guid>https://blog.youkuaiyun.com/wangpu_baggio/article/details/119808125</guid><author>wangpu_baggio</author><pubDate>Thu, 19 Aug 2021 18:08:04 +0800</pubDate><description><![CDATA[序列型和坐标型的最大区别是序列型不是简单的用坐标表示DP值，而一般需要加上状态。





https://leetcode.com/problems/house-robber/

按照解决DP问题的一般情况来，我们先分析最后一步。最后一步的最优策略中，有可能偷，也可能不偷最后一栋房。那么为了方便计算，一般我们可以考虑在dp中加入一个状态。





所以这个问题可以简化为是否偷I – 1套房子。那么我们可以将DP定义简化：



代码就很简单了：


public int rob(int[] nums) ]]></description><category></category></item><item><title><![CDATA[专题：动态规划(Dynamic Programming)模式(1. 坐标型)]]></title><link>https://blog.youkuaiyun.com/wangpu_baggio/article/details/119777207</link><guid>https://blog.youkuaiyun.com/wangpu_baggio/article/details/119777207</guid><author>wangpu_baggio</author><pubDate>Wed, 18 Aug 2021 12:00:16 +0800</pubDate><description><![CDATA[动态规划（Dynamic programming，简称DP）是一种在数学、管理科学、计算机科学、经济学和生物信息学中使用的，通过把原问题分解为相对简单的子问题的方式求解复杂问题的方法。

 动态规划类的题目在leetcode中是一大类，可以使用DP求解的问题一般有如下几个特点：

计数
1.1）有多少种方式跳到右侧，多少种方式走到右下角

   1.2）有多少种方法选出K个数使得和是Sum

 2） 求最大值和最小值

...]]></description><category></category></item><item><title><![CDATA[专题：拓扑排序(Topological sort)模式]]></title><link>https://blog.youkuaiyun.com/wangpu_baggio/article/details/119355392</link><guid>https://blog.youkuaiyun.com/wangpu_baggio/article/details/119355392</guid><author>wangpu_baggio</author><pubDate>Tue, 03 Aug 2021 17:36:37 +0800</pubDate><description><![CDATA[拓扑排序用于查找相互依赖的元素的线性排序。例如，如果事件“B”依赖于事件“A”，则“A”按拓扑顺序排在“B”之前。

该模式定义了一种简单的方法来理解对一组元素执行拓扑排序的技术。

该模式的工作方式如下：

初始化

a) 使用 HashMap(或List数组)将图存储在邻接列表中;

b) 使用 HashMap 来构建邻接表, 计算所有节点的入度

c) 将所有入度为0的顶点都将作为源并存储在队列queue中。



a) 对于每个源，执行以下操作：

-i) 将其添加到排序列表中。

— ii) 从图]]></description><category></category></item><item><title><![CDATA[专题：0/1背包问题(0/1 Knapsack)模式]]></title><link>https://blog.youkuaiyun.com/wangpu_baggio/article/details/119296022</link><guid>https://blog.youkuaiyun.com/wangpu_baggio/article/details/119296022</guid><author>wangpu_baggio</author><pubDate>Sun, 01 Aug 2021 11:26:56 +0800</pubDate><description><![CDATA[背包问题是一类经典的动态规划问题，它非常灵活，需要仔细琢磨体会，本文对背包问题中基本的0/1背包问题和对应的leetcode题目作一个总结，期望可以用一套框架解决背包问题。

01 背包问题：
最基本的背包问题就是 01 背包问题：背包承重为 Capacity, 现在有n个物品，物品重量 w[n], 物品价值 v[n]。如何选择物品价值最大？

特点：每种物品仅有一件，可以选择放或不放, 即0/1.

1.1 背包问题具备的特征：

是否可以根据一个 target（直接给出或间接求出），target 可以是]]></description><category></category></item><item><title><![CDATA[专题：多路归并(K-way merge)模式]]></title><link>https://blog.youkuaiyun.com/wangpu_baggio/article/details/118971784</link><guid>https://blog.youkuaiyun.com/wangpu_baggio/article/details/118971784</guid><author>wangpu_baggio</author><pubDate>Wed, 21 Jul 2021 17:26:47 +0800</pubDate><description><![CDATA[多路归并可以帮助解决涉及一组排序数组的问题。

每当获得“K”个排序数组时，都可以使用堆(Heap)高效地对所有数组的所有元素执行排序遍历。您可以在最小堆中推送每个数组的最小元素以获得整体最小值。获得整体最小值后，将同一数组中的下一个元素推送到堆中。然后，重复此过程以对所有元素进行排序遍历。

图示如下：

多路归并三个list



该模式通用算法如下所示：



在最小堆中插入每个数组的第一个元素。
	从堆中取出最小（顶部）元素并将其添加到合并列表中。
	从堆中移除最小元素后，将同一列表的下一个元素插入]]></description><category></category></item><item><title><![CDATA[专题：Top K元素(Top K elements)模式]]></title><link>https://blog.youkuaiyun.com/wangpu_baggio/article/details/118808149</link><guid>https://blog.youkuaiyun.com/wangpu_baggio/article/details/118808149</guid><author>wangpu_baggio</author><pubDate>Fri, 16 Jul 2021 16:53:41 +0800</pubDate><description><![CDATA[当看到从一个集合中寻找最大/最小/最频繁的Top K个元素时，可以套用这个模式。

解决Top K问题的最好数据结构是堆(Heap)。这个模式也是使用大根堆/小根堆去解决Top K问题，流程如下：

插入K个元素到小根堆/大根堆中；
	遍历剩下的元素，如果发现小于/或者大于堆中的元素，则将堆层的元素出队列，然后插入该元素。
	最后留下的即为符合要求的元素。


从[3, 1, 5,12,2,11]中找到最大的3个元素的流程图如下：



如何识别符合这个模板的问题：

从一个给定集合中寻找最大/最小/最频繁]]></description><category></category></item><item><title><![CDATA[高频刷题-最大最小堆(Two heaps)专题]]></title><link>https://blog.youkuaiyun.com/wangpu_baggio/article/details/118756624</link><guid>https://blog.youkuaiyun.com/wangpu_baggio/article/details/118756624</guid><author>wangpu_baggio</author><pubDate>Thu, 15 Jul 2021 12:12:32 +0800</pubDate><description><![CDATA[有许多问题是关于一组元素，可以把他们分成两个部分。为了解决问题，我们会对前半部分元素的最小的元素、另一半元素的最大的一部分感兴趣。Two heaps模式就是一种有效解决这样的问题的方法。

Two heaps使用了两个堆：一个最小堆找到最小的元素，最大堆找到最大的元素。我们存储前半部分元素到最大堆种，后半部分元素到最小堆种。这样，如果我们需要计算中位数，直接可以根据这两个堆的堆顶元素就可以计算出来。

Two heaps模式适用于如下场景：

在Priority Queue, 日程安排(Scheduling]]></description><category></category></item><item><title><![CDATA[高频刷题-二叉树深度优先搜索(Depth First Search)专题]]></title><link>https://blog.youkuaiyun.com/wangpu_baggio/article/details/118679782</link><guid>https://blog.youkuaiyun.com/wangpu_baggio/article/details/118679782</guid><author>wangpu_baggio</author><pubDate>Mon, 12 Jul 2021 17:24:07 +0800</pubDate><description><![CDATA[下面我们介绍DFS遍历算法。这个算法在解决需要遍历树的问题时非常有效。

不同于广度优先遍历算法，DFS是一头遍历到节点节点，因此需要保存每次遍历的父节点的信息。通常我们是使用递归的方式进行遍历，也可以采用statck去保存。

从特点可以看出，DFS的空间复杂度和递归的深度有关，是O(H)，H是树的最大深度。

每个节点都会遍历一次，时间复杂度也是O(N). N为节点数。

下面我们还是直接看题目:



https://leetcode.com/problems/path-sum/

计算二叉树的路径和]]></description><category></category></item><item><title><![CDATA[高频刷题-二叉树广度优先搜索(Breath First Search)专题]]></title><link>https://blog.youkuaiyun.com/wangpu_baggio/article/details/118652855</link><guid>https://blog.youkuaiyun.com/wangpu_baggio/article/details/118652855</guid><author>wangpu_baggio</author><pubDate>Sun, 11 Jul 2021 12:24:24 +0800</pubDate><description><![CDATA[今天我们介绍二叉树的BFS和DFS。以前二叉树专题的时候已经使用BFS和DFS算法去解决过二叉树的相关问题。这次我们再总结一下BFS和DFS算法的特点和模板。

因为BFS算法的特点，在解决二叉树按层级遍历问题时非常有用。

我们将使用一个队列(Queue)来跟踪的所有节点级别之前我们跳到下一个级别。这也意味着,算法的空间复杂度是O (N),其中N是节点在每一层级的最大数量。

 下面我们直接看题目:



https://leetcode.com/problems/binary-tree-le...]]></description><category></category></item><item><title><![CDATA[高频刷题-就地反转链表(In-place Reversal of a Linked List)专题]]></title><link>https://blog.youkuaiyun.com/wangpu_baggio/article/details/118570632</link><guid>https://blog.youkuaiyun.com/wangpu_baggio/article/details/118570632</guid><author>wangpu_baggio</author><pubDate>Thu, 08 Jul 2021 11:52:17 +0800</pubDate><description><![CDATA[这次我们将介绍就地反转一个链表的模板，这个模板解决涉及逆转一个链表的时候非常有用，我们可以做到不使用额外的内存，在时间复杂度为O(n)的情况下完成。

该文参考如下博客:

https://emre.me/coding-patterns/in-place-reversal-of-a-linked-list/

我们直接看这个题目:



https://leetcode.com/problems/reverse-linked-list/

首先我们介绍iteration方法，这是一种遍历整个链表结构的方法.]]></description><category></category></item><item><title><![CDATA[高频刷题-Interval相关问题专题]]></title><link>https://blog.youkuaiyun.com/wangpu_baggio/article/details/118514216</link><guid>https://blog.youkuaiyun.com/wangpu_baggio/article/details/118514216</guid><author>wangpu_baggio</author><pubDate>Tue, 06 Jul 2021 09:57:55 +0800</pubDate><description><![CDATA[该博文参考了如下blog：

https://emre.me/coding-patterns/merge-intervals/

https://leetcode.com/discuss/general-discussion/794725/General-Pattern-for-greedy-approach-for-Interval-based-problems/658450

Interval中文意思是间隔，可以理解为区间。生活中很多可以描述为interval，例如会议时间的区间，公交车运行站点区间等等]]></description><category></category></item><item><title><![CDATA[高频刷题-循环排序(Cyclic Sort)专题]]></title><link>https://blog.youkuaiyun.com/wangpu_baggio/article/details/118418026</link><guid>https://blog.youkuaiyun.com/wangpu_baggio/article/details/118418026</guid><author>wangpu_baggio</author><pubDate>Fri, 02 Jul 2021 16:11:39 +0800</pubDate><description><![CDATA[参考如下链接:

https://emre.me/coding-patterns/cyclic-sort/



以前的文章我们介绍了滑动窗口(Sliding Window), 双指针(Two Pointers), 快慢指针(Fast &amp; Slow Pointers)等模板。今天，我们介绍一种新的解题模板，称为循环排序(Cyclic sort或Cycle sort)。这是一种非常有用的解决这种数组：包含的数字在给定数组的长度范围内，寻找缺失或重复的数字问题的方法。

下面图示下：

对于数组[2, ]]></description><category></category></item><item><title><![CDATA[高频刷题-双指针法(two-pointers)专题]]></title><link>https://blog.youkuaiyun.com/wangpu_baggio/article/details/118306142</link><guid>https://blog.youkuaiyun.com/wangpu_baggio/article/details/118306142</guid><author>wangpu_baggio</author><pubDate>Mon, 28 Jun 2021 16:12:25 +0800</pubDate><description><![CDATA[双指针法是一个可以是一个算法模板，经常被运用在有序的数组或列表中。和滑动窗口不同的是，此时的双指针是从两侧到中间，通俗点也可以称为夹逼法。例如，从一个有序数组中找到符合一定条件的元素组。

直接遍历整个集合，需要进行O(n^2)或者O(n^3)复杂度的遍历。而双指针的夹逼法，通常可以只遍历一次即可找到结果，有效的节省了时间复杂度和空间复杂度。



确定何时使用双指针方法的方法：



它将处理排序数组（或链表）并需要找到一组满足某些约束的元素的问题
数组中的元素集是一对、三元组，甚至是子数组。...]]></description><category></category></item><item><title><![CDATA[高频刷题-滑动窗口(Sliding Window)专题]]></title><link>https://blog.youkuaiyun.com/wangpu_baggio/article/details/118223278</link><guid>https://blog.youkuaiyun.com/wangpu_baggio/article/details/118223278</guid><author>wangpu_baggio</author><pubDate>Fri, 25 Jun 2021 16:19:14 +0800</pubDate><description><![CDATA[滑动窗口算法多用于处理数组（Array）, 字符串（String）或者链表（LinkedList）中关于子字符串（Substrings）, 子数组(Subarrays, Sublists)等连续问题。该算法可以将多重嵌套的循环转化为单循环，从而降低时间复杂度(O(n))。滑动窗口是同向双指针的一个类型。



注意上述的滑动窗口示意图是固定大小，而现实中窗口大小也可以是不固定的。

下面给出滑动窗口算法的一个模板，来源于leetcode并做了一些理解上的修改。注意模板给出的是一个非固定大小...]]></description><category></category></item><item><title><![CDATA[高频刷题-74. Search a 2D Matrix]]></title><link>https://blog.youkuaiyun.com/wangpu_baggio/article/details/118083832</link><guid>https://blog.youkuaiyun.com/wangpu_baggio/article/details/118083832</guid><author>wangpu_baggio</author><pubDate>Mon, 21 Jun 2021 11:59:30 +0800</pubDate><description><![CDATA[https://leetcode.com/problems/search-a-2d-matrix/

这个题目看得出来matrix从头到尾就是一个排序的集合，所以二分查找是必然的。唯一要做的处理就是每次换行的时候怎么进行跳转。

每次我们计算了中间值后，可以从中间数算出对应的matrix的长和宽：

 Matrix 长 = mid / column;

 Matrix 宽 = mid % column;

这样这个题目直接套用二分查找的模板就可以了，这里我们采...]]></description><category></category></item><item><title><![CDATA[高频刷题-二分查找(Binary Search)专题]]></title><link>https://blog.youkuaiyun.com/wangpu_baggio/article/details/118031309</link><guid>https://blog.youkuaiyun.com/wangpu_baggio/article/details/118031309</guid><author>wangpu_baggio</author><pubDate>Fri, 18 Jun 2021 17:59:54 +0800</pubDate><description><![CDATA[leecode 中有很多binary search的题。一般而言，当一个题目出现以下特性时，你就应该立即联想到它可能需要使用二分查找：

待查找的数组有序或者部分有序
	要求时间复杂度低于O(n)，或者直接要求时间复杂度为O(log n)


二叉搜索的思想很好理解，但是其中的边界条件却很繁琐，很多时候写出来的代码不能很好的处理边界条件。例如：



同时，二叉搜索有很多的变体，例如：



对于这些条件和边界的总结，qq下面这篇文章可以说彻底的让你理解清楚。

https://leetcode-cn.c.]]></description><category></category></item></channel></rss>