自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 接雨水的几种思路

1. 从列的角度看(每列可以蓄水多少)以柱子1 为例,它能贡献的当列需水量取决于左右最高的两根柱子0和4, 每列 iii 蓄水的高度为min(hleft,hright)−himin(h_{left}, h_{right}) - h_imin(hleft​,hright​)−hi​其中 h_{left}, h_{right} 指的是i左边和右边最高的柱子高度所以最简单的方式就是,我们对每个i去向左向右搜索最高的柱子,然后计算:for(int i=0; i<n; i++){ //找左边最

2021-08-30 15:56:35 149

原创 双栈法解计算器

输入:s = “3+2*2”输出:7一个栈用来存储数字,一个栈用来存储运算符。为什么运算符要存储? 因为不确定后面有没有运算级更高的出现,如果有,后面的先算,所以存储在这里等待后面的可能性。当后面的字符出现,如果没有运算级别比栈顶高: + 后面出现 -, 那就说明此时这两个元素间是按顺序计算的,所以 - 放进去之前,+要弹出先行计算了,把结果放入数字栈后,-才入栈。运算符栈中最多有两个元素 (+ or -), (* or /) int calculate(string s) { .

2021-08-26 10:49:36 232

原创 股票买卖——状态如何表示与转换

股票问题:给你股票每天的价格,限定你只能进行K次交易(buy and sell), 求最大的收入。求第n天交易k次的收入,一般做动态规划的习惯思路会想到:dp[n][k],所以会想到用 dp[i][j] 表示第i天为止进行 k 次交易的利润。我们思考每天的选择,只有三种:sell, buy, keep因为sell, buy是有前序关系的,必须前面有buy才能sell, 因此我们的状态必须加上一维表示是否前面buy过。dp[][][0]表示没buy呢dp[][][1]表示已经buy过了状态

2021-08-13 15:20:43 205

原创 二分易错点分析

二分就是每次缩小一半查找区间,因为判断过那个查找区间无效。我以前的版本while(l<=r){ int mid = (l+r)/2; if( mid is the target) return; if(mid < target) l = mid + 1; else r = mid -1;}公有两个版本普适性更强些能够找到符合check条件的最大or最小的第一个数区间的划分:[ l, mid ] 和 [ mid+1, r ][ l, mid-1] 和 [

2021-06-23 00:13:29 114

原创 力扣 664. 奇怪的打印机

有台奇怪的打印机有以下两个特殊要求:打印机每次只能打印由 同一个字符 组成的序列。每次可以在任意起始和结束位置打印新字符,并且会覆盖掉原来已有的字符。给你一个字符串 s ,你的任务是计算这个打印机打印它需要的最少打印次数输入:s = “aba”输出:2解释:首先打印 “aaa” 然后在第二个位置打印 “b” 覆盖掉原来的字符 ‘a’。分析例子: aba 最简单的打印方式是分成三段,每次打印a,b,a。但是更简单的是 aaa–> aba,这里我们可以认为右侧的a是左侧延申来的,.

2021-05-24 14:40:09 146

原创 字符串分割专题

分割回文字符串给你一个字符串 s,请你将 s 分割成一些子串,使每个子串都是 回文串 。返回 s 所有可能的分割方案。所有方案:回溯 void backtrack(string& s, vector<string>& temp, int id, vector<vector<string>>& res){ if(id == s.size()){ res.push_back(temp);

2021-04-08 20:53:01 374

原创 树的遍历——迭代法

不适用递归而使用栈来实现树的前序,中序,后序遍历。假设我们要遍历一刻二叉树,结果放进result中。栈具有反转顺序的特点,假如最简单一棵二叉树A,两个儿子B、C, 正的顺序是A B C, 那么入栈顺序肯定是C B A。所以根据倒序特点:(右边是入栈顺序)前序遍历:中 左 右 ——> 右 左 中中序遍历:左 中 右 ——> 右 中 左后续遍历: 左 右 中——> 中 右 左递归来说,虽然访问顺序不同,但是递归的过程是一样的,都是由上到下这样,只不过访问根节点(放入当前节点到r

2021-04-08 16:07:33 464

原创 堆排序

堆的性质(大根堆):父节点大于左右儿子堆排序建堆每次拿堆顶元素和末尾 i 进行交换(相当于 i~n 都是排好序的)。交换后堆顶破坏了堆的性质,把它堆化。建堆从最后一个非叶子节点 r 开始,对它记性siftDown(r)siftDown(r)siftDown(r) 操作,也就是如果它的儿子比它大就交换。如果交换后破坏了儿子为根的堆,那么向下递归。//siftDown操作相当于维护以r为根的堆void siftDown(vector<int>& nums, int

2021-03-25 13:53:07 55

原创 LCA问题

二叉树的LCA最近公共祖先的两种情况:p在左子孙中,q在右子孙中——找到了p,q在当前root的一侧root碰到 p | q了——找到了root还没碰到p|q,这一侧成为新rootdfs遍历左右子树,如果左右子树都能查到p or q,则表明 p 和 q 分别在左右子树中,因此,当前节点即为最近公共祖先;如果左右子树其中一个不为空,则返回非空子树里的较高p or q。TreeNode* LCA(TreeNode* root, TreeNode* p, TreeeNode* q)

2021-03-20 16:10:46 77

原创 回溯法总结题型——组合排列、子集、分割

注:图片借鉴代码随想录组合问题回溯法解决组合问题的最基础题型我们把这个选k个数的流程用树来画出来:我们可以看到,组合问题的特点就是对于1来说,取过1的分支已经在走了,则其他分支不需要考虑1了(和排列不同,排列的话在不同层的1是不一样的情况)。我们递归遍历时,下一层都从上一层的id+1开始取数。 void backtrack(int k,int n, int nowid, vector<vector<int>>& res, vector<int>

2021-03-13 10:31:44 155

原创 反转链表2-虚拟头结点

反转从位置 m 到 n 的链表。请使用一趟扫描完成反转。经典题,题目不难但是容易链表操作出错。先写下核心思路就是把m-n的链表截取出来然后对它反转再拼接回去。链表反转的核心是:now->next = pre,更新后now->next失效,所以需要提前保存。我这里容易出错的地方在于拼接回去的时候,尤其要记得特殊情况:从头开始反转了的话,head指针是要变的。这里最好的做法是用虚拟头节点。而且虚拟头结点还有一个好处,就是万一我们的leftNode就是头结点,pre有确切的点可以使用。官方

2021-03-12 19:48:45 253

原创 正则表达式匹配题

给你一个字符串 s 和一个字符规律 p,请你来实现一个支持 ‘.’ 和 ‘*’ 的正则表达式匹配。‘.’ 匹配任意单个字符‘*’ 匹配零个或多个前面的那一个元素输入:s = “aa” p = “a*”输出:true思路:i, j 分别是s,p的遍历下标,dp[i][j]表示s[:i]和p[:j]是否匹配。普通字符和‘.’字符都很好处理,匹配就从dp[i-1][j-1]过来,不匹配就false。难点在于星号*,它可以匹配任意个字符,状态就不是简单的从i-1,j-1过来这么简单。星号肯定要和前

2021-03-12 13:12:03 226

原创 单调队列

和单调栈一样维持一个单调性的队列,这个队列中的数比实际数组的数要少,因为删去了不必要的部分。我遇到的题一般会把单调队列作为一个辅助数据结构来存储当前状态。以递减的单调队列为例子,它的特点就是每次都能取到队首最大的元素,这也就是我们当前状态的最大元素。以例题来看具体过程。剑指offer59 队列最大值请定义一个队列并实现函数 max_value 得到队列里的最大值,要求函数max_value、push_back 和 pop_front 的均摊时间复杂度都是O(1)。思路:我们除了要知道当前最大元素,

2021-03-11 16:14:35 61

原创 剑指 Offer 36. 二叉搜索树与双向链表

输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的循环双向链表。这道题让我们按照中序遍历的顺序链接树的节点形成循环链表。最简单的方法莫过于用vector或者queue记录访问顺序,然后得到序列挨个链接即可。当然我们这里希望时间效率更高就得一边遍历一边连接好。难点在于如何在遍历的过程中处理前后指针。那么最直接的想法就是用一个Pre指针记录前一个遍历的节点,然后每次对于当前节点,链接和pre的双向箭头。中序遍历:dfs(left)——root处理——dfs(right), 用pre表示前一个节点,

2021-01-08 14:37:15 53

原创 0/1背包类相关题目

leetcode 416. Partition Equal Subset SumGiven a non-empty array nums containing only positive integers, find if the array can be partitioned into two subsets such that the sum of elements in both subsets is equal.Input: nums = [1,5,11,5]Output: trueExp

2021-01-08 13:04:05 91 1

原创 KMP学习记录

Next数组是什么? 为什么需要它在进行字符串匹配的时候,我们定义模式串P和长的字符串S,以下所指的移动都默认是移动模式串P。暴力方法:一次移动一格,从P的头部查看是否匹配,一旦不匹配继续往后移动一格,重新匹配一次移动一格是很慢的,也是没有必要的,事实上,我们可以将移动情况分为两种:针对第一种情况我们可以发现,要使得这种情况能发生新匹配,必然是三个红圈的地方要一样,那么也就是蓝色部分存在相同的前后缀子串。当我们知道这个前后缀的公共长度是 k, 那么也就是 P 右移了 j - k,也就是本来下

2021-01-07 21:15:38 111 1

原创 91. Decode Ways (DP)

将数字字符解析为A-Z表示的字符串,有几种解析方法:Input: s = “12”Output: 2Explanation: “12” could be decoded as “AB” (1 2) or “L” (12).因为A-Z最多表示2位数的数字,这里的状态转移理解为向解析字符串后添加一个字母226 = 22 + 6 : 22解析的所有字符串结尾添加 F226 = 2 + 26 : 2解析的所有字符串结尾添加Zdp[i]=dp[i−1]+dp[i−2]dp[i] = dp[i-1]

2020-12-31 18:10:03 111

原创 Floyd‘s cycle detection 问题

首先来看 LeetCode142. Linked List Cycle II给定一个链表,求环是否存在以及环开始的地方。Floyd判圈算法可以用赛跑的想法去理解,环形跑道两个人跑步,跑的快的肯定会再一次追上跑的慢的。这个比较好理解,关键是如何确定环开始。如果只有环且同时出发,那快的第一次再遇慢的比他多跑一圈,但是这里因为有一段直线操场,快的会先进入环形,等到慢的进来可能快的已经跑了几圈了。所以这里快的比慢的多跑了K圈。我们使用一对快慢指针来模拟这两个人,快指针一次两个单位前进,慢指针一次一个。假设

2020-12-28 16:33:39 79

原创 LeetCode 413. Arithmetic Slices

题目Return the number of arithmetic slices in the array A.数组A中的递增子数组的总数。输入:A = [1, 2, 3, 4]输出:3思路这道题发现官方是把它当成dp的思路,我是把它用滑动窗口的想法做的,窗口标记为[start, end),表明这个窗口中是当前完整递增数组。就拿题目例子来说,4加入进去的时候总数增加了多少呢? 这其实取决于当前这个递增数组的长度。这里增加的是[1,2,3,4] 和 [2,3,4] 这两个子数组,也就是增加了1开

2020-12-22 21:44:28 53

原创 剑指offer11. 旋转数组的最小数字

把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如,数组 [3,4,5,1,2] 为 [1,2,3,4,5] 的一个旋转,该数组的最小值为1。输入:[3,4,5,1,2]输出:1思路这道题简单的地方在于一眼能看出来是二分,难点在于特殊情况的考虑。旋转操作让这个数组可以分成两个递增的数组,并且右边那个要更小。最简单的情况,假设没有重复元素,左边数组的开头设为start, 那么我们始终有:element[right]&lt

2020-12-22 12:50:19 61

原创 剑指offer 62. 圆圈中最后剩下的数字

剑指offer 62. 圆圈中最后剩下的数字题目0,1,n-1这n个数字排成一个圆圈,从数字0开始,每次从这个圆圈里删除第m个数字。求出这个圆圈里剩下的最后一个数字。例如,0、1、2、3、4这5个数字组成一个圆圈,从数字0开始每次删除第3个数字,则删除的前4个数字依次是2、0、4、1,因此最后剩下的数字是3。输入: n = 5, m = 3输出: 3限制:1 <= n <= 10^5, 1 <= m <= 10^6思路1模拟法:按照题目的过程模拟一个头尾相连的链表,每

2020-12-21 15:27:37 92 1

原创 Leetcode 4. Median of Two Sorted Arrays

Leetcode 4.Median of Two Sorted ArraysGiven two sorted arraysnums1andnums2of sizemandnrespectively, returnthe medianof the two sorted arrays.找两个已经有序数组合起来中的中位数两个有序数组,很容易想到归并排序,用归并的思想这道题也很好做,两个数组分别需要扫描一次,时间效率为O(m+n)。 这道题难点在于如何达到要求的O(log(m...

2020-12-21 14:58:47 124 1

空空如也

空空如也

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

TA关注的人

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