07 2020 档案
摘要:题目说了,峰值元素就是大于相邻左右元素的元素,又说了nums[-1] = nums[n] = -∞,所以我们就寻思着,如果nums[0]比nums[1]大,再加上nums[-1]是负无穷,那么nums[0]不就是一个峰值元素了吗。 如果nums[0]不比nums[1]大,那么我们接着把nums[1]
阅读全文
摘要:这题做法比较贼,让两个指针p, q分别指向两个链表的头,然后只要两个指针不为空且指向的位置不同,就都向后移动,当一个指针为空的时候,就指向另一个链表的头。 比如上面这图,假设相交部分之前,两个链表的长度分别是a,b,相交链表之后的长度为c。 那么p指针走了a + c长度(走完第一个链表)之后,指向第
阅读全文
摘要:要能够在常数时间内检索到栈内最小元素,我们可以额外开一个栈,这个额外的栈的栈顶元素存放目前栈内的最小元素,每次栈内压入一个新元素,辅助栈也压入一个元素,也就是把新元素和原栈顶元素比较,较小的那个就是新的最小元素,压入辅助栈的栈顶;原栈弹出栈顶元素的时候,辅助栈也弹出栈顶元素,这样,不管什么时候,辅助
阅读全文
摘要:经过旋转后的数组,满足这样一个性质,最小值右边的元素,都大于等于最小值(因为这题有重复元素,所以有可能等于),最小值左边的元素,都大于等于最小值。 所以每一次二分,我们可以与当前区间的最左边或最右边进行比较,确定最小值的位置。 这里我们每次将区间中点的值nums[mid]与区间右端点nums[rig
阅读全文
摘要:题目说了是对升序的数组做旋转得到的数组,可以考虑二分。 因为做过旋转了,所以不能直接用二分。 找一下规律,旋转数组原来是升序的,那么最小的元素就是旋转前的第一个元素。 旋转之后,相当于把原来升序数组的前面某些部分放到了数组的后面,那么这个数组就满足,在最小的元素之前的部分数组依旧是升序的,然后最小的
阅读全文
摘要:要求乘积最大的子数组(子数组一定都是连续的),可以暴力枚举子数组起点和终点,求和。但是肯定超时。 如果用动态规划,则只需要一遍扫描就可以得出结果。 可以用maxProduct[i]表示以i结尾的最大的子数组乘积。 如果所有nums[i]都是正数,则maxProduct[i]就是max(nums[i]
阅读全文
摘要:题意是要把原字符串中所有的单词划分出来,倒序用一个空格的间隙来连接字符串,我们只需要划分出所有的单词,然后把它们连接起来,每两个单词之间放一个空格就好了。 分割空格之间的单词,很容易想到用双指针进行分割,只需要找到每个单词的第一个字母(也就是第一个不为空格的字母),然后左指针指向这个单词,右指针不断
阅读全文
摘要:1523. 在区间范围内统计奇数数目 先计算从low到high一共有多少个数: int diff = high - low + 1; 找规律发现,如果low和high都是奇数,那么奇数个数就是diff上取整,其他情况奇数数目都是diff下取整。 class Solution { public: in
阅读全文
摘要:经典dp问题,用dp[i]表示前i个字符解码方案的总数。 显然dp[0]=1(空字符也相当于一种解码方案), 然后从小到大递推计算dp数组,如果当前当前数字不是0(也就是大于等于1小于等于9),则当前字符可以连接在之前所有字符之后成为一个新方案。 当前字符是0是不行的,0不能映射成英文字母。 所以有
阅读全文
摘要:DFS枚举所有子集,对于每个数字,假设出现次数是cnt,则枚举这个数字的出现次数0,1, 2,.....cnt,其他数字同理。 所以解空间是指数级的。 要计算所有数字出现的次数,可以直接排序,这样同样的数字都是相邻的。 然后一个for循环枚举每个数的添加次数,假设一个数字的出现次数是cnt,则枚举它
阅读全文
摘要:找规律,格雷码的一种生成方法如下图。对于n先将n-1的所有格雷码复制一下,然后轴对称所有n-1的格雷码,然后前半部分补0,后半部分补1, 就得到了n的格雷码。 class Solution { public: vector<int> grayCode(int n) { vector<int> res
阅读全文
摘要:归并两个已排序数组为一个数组,不同于归并排序的归并用一个额外的数组,这里在第一个数组预留出足够的空间,所以需要直接在第一个数组里存放原来的两个数组的所有元素。 归并排序里,是额外开一个数组,然后两个指针分别从第一个数组和第二个数组的开头进行比较,比较小的那一个元素加入新数组中,然后某个数组为空之后,
阅读全文
摘要:判断S2是否是S1的扰乱字符串。根据题目的定义,S1如果经过若干次对于部分子串的翻转操作能够得到S2,则S2是S1的扰乱字符串。 首先,如果S2是S1的扰乱字符串,那么S1中每个字符的出现次数必然和S2中每个字符的出现次数一致,也就是说,我们用两个字符串S3、S4备份一下S1和S2, 对S3和S4排
阅读全文
摘要:要根据链表节点的值是否大于等于x将链表划分为两段,首先需要链表中大于等于x和小于x的节点的个数,所以无法直接在原链表上做修改。 既然要分开大于等于x的值和小于x的值,我们可以考虑开两个链表,这样按顺序扫描原链表的时候,小于x的值接到第一个链表,大于等于x的值接到第二个链表。 然后再把这两个链表连接起
阅读全文
摘要:这题其实是84题的进阶版。 要求最大矩形,同样也是枚举所有矩形,关键就在于如何枚举。 如果直接枚举所有起点和终点,复杂度最起码是O(n^4),超时。 所以要换种方式枚举,可以考虑固定住所有矩形的底边,比如以每一行作为底边,枚举以这个底边,往上有哪些矩形,分别计算面积。 固定住底边之后,网上所有的连续
阅读全文
摘要:要求能勾勒出来的矩形的最大高度,很自然的想法就是枚举所有矩形的宽度和高度,再通过高度和宽度的乘积求出所有矩形的面积,这样就可以知道最大矩形的面积了。 暴力做法是,枚举所有矩形的宽度(也就是枚举左边界和右边界),再求出左边界和右边界内柱子的最小高度(瓶颈高度),然后得到矩形的面积。 代码如下: cla
阅读全文
摘要:原题链接 这道题就是单调栈最经典的应用,单调栈往往就是求一个数组中每个元素左边(之前)的元素中离它最近的比它小的元素。 首先很容易想到暴力做法,对于每一个元素,从当前元素的前一个元素开始往前遍历,第一个满足小于当前元素的元素就是答案,遍历完数组都不存在元素比当前元素小,则输出-1. 代码如下: #i
阅读全文
摘要:原题链接 数组模拟队列和数组模拟栈其实很类似,都是用一个数组来存储元素,用指针表示当前可以操作的位置。 区别就是栈只能在栈顶进行操作,所以只需要有一个top指针指向栈顶。 而队列可以在队头和队尾都进行操作(出队、入队),所以需要两个指针head和tail指向队头和队尾。 如果有元素入队,则tail加
阅读全文
摘要:原题链接 题意是用数组模拟一个栈,支持四种栈操作:在栈顶插入元素,弹出栈顶元素,查询栈顶元素,查询栈是否为空。 用数组模拟栈只需要开一个数组存储栈元素,再用一个额外的变量top表示当前栈顶元素下标。 直接看代码吧: #include<bits/stdc++.h> using namespace st
阅读全文
摘要:之前写了数组实现单链表,提到了数组实现链表比指针实现最大的优点就是快,可以随机存取,而且不用new节点。 在图论的题目里用到邻接表,往往都是用数组实现。 数组实现双链表比单链表就多了一些对于左指针的操作。 为了实现的方便,不像在单链表实现里用一个额外的变量head去记录链表的头节点。 而是直接用两个
阅读全文
摘要:单链表常见的实现方法有两种,一种方式是定义一个结构体表示链表节点。比如: struct node{ int val; node* next; }; 然后就是通过next指针将链表的所有节点连接起来。如果涉及到链表节点的插入和删除操作,则只需要修改链表节点的指针即可。 这种方式有个明显的缺点,就是不能
阅读全文
摘要:5177. 转变日期格式 思路:按照空格划分出年月日,年已经是数字形式,不需要做处理。月是英文单词的缩写,需要对应到相应的数字。 对于日,只需要把结尾的英文序数词去掉,只留下数字即可。 这里要注意月和日可能是个位数,这种情况下要在前面补一个0. class Solution { string mon
阅读全文
摘要:原题链接 来源:剑指offer, Hulu面试题 题意很简单。给定一个单链表,反转这个单链表,返回翻转后的头节点。 方法一 借助栈的性质 要将链表翻转,很容易想到借助栈的后进先出的性质来改变链表的顺序。 将链表节点顺序压入栈中,链表节点全部进栈以后,取栈顶元素作为新链表的头节点,然后将元素不断出栈,
阅读全文
摘要:暴力枚举即可,注意特判k为0的情况。 class Solution { public: vector<int> divingBoard(int shorter, int longer, int k) { if(k == 0) { return {}; } vector<int> res; set<i
阅读全文
摘要:判断当前节点currentNode的值和它的next指针所指向的节点的值是否相等,如果相等,就一直向后移动next指针直到遇到 next指针所指节点的值和currentNode的值不相等,这时将currentNode的next指针指向这个不相等的节点即可。 当currentNode和currentN
阅读全文
摘要:题意是要删除一个排序链表里所有重复出现的数字,链表里留下的数字都是只出现一次的数字。 思路:用两个指针currentNode和nextNode扫描一遍有序链表,最开始初始化currentNode为链表的附加头节点dummy, nextNode为currentNode的下一个节点,然后不断判断next
阅读全文
摘要:方法一 先排序后二分 要判断数组里是否存在target,可以先对数组排序,然后直接二分查找。 这样时间复杂度是O(nlogn)。 class Solution { public: bool search(vector<int>& nums, int target) { sort(nums.begin
阅读全文
摘要:这题和LeetCode第51题做法一样,只不过不是记录具体方案,而是个数。分析见第51题。 代码如下: class Solution { int res = 0; int n; vector<string> path; vector<bool> cols, diagram, anti_diagram
阅读全文
摘要:题意是给定一个N × N大小的棋盘,求不同的N皇后方案的个数。N皇后的方案指,N个皇后放在棋盘上,互相不能攻击到。 国际象棋里,皇后可以横竖斜走若干步,所以一个方案是合法的,必须满足任意一个皇后所在的行、列、对角线、斜对角线都没有其他皇后。 我们要求的就是这样的方案的个数。 由于每行只能放一个皇后,
阅读全文
摘要:题意是给定一个已排序数组,我们需要原地修改数组,使得相同元素最多留下2个,并且返回新的数组的大小。 这题还是双指针做法,最开始左右指针都在0位置,左指针表示新的已排序数组的末尾元素位置, 右指针从左向右遍历逐个判断元素是否可以加入“新数组”中。 由于相同元素最多只能留两个,且数组是已排序的,所以对于
阅读全文
摘要:又是一道DFS回溯,枚举二维字符数组的所有字符作为起点,判断以这个字符作为起点DFS是否能得到word,可以就返回true, 如果所有起点都不行就返回false。 DFS函数就按照方向进行搜索,上下左右是个方向分别去搜,返回的情况有: 1. 某方向下一个字符和word的下一个字符不相等,回溯,返回f
阅读全文
摘要:方法一(DFS回溯) 求出所有可能的子集,就是要遍历一遍DFS递归树,把所有子集全都压入结果数组中。 class Solution { vector<vector<int>> res; vector<int> onePath; //onePath是递归树的一条路径(一个子集) public: vec
阅读全文
摘要:DFS回溯,从左至右选数,加入一个一维数组oneCombination中,当oneCombination的大小等于k,表示已经选了k个数, 将oneCombination压入结果数组res中。 DFS的函数签名可以写为void DFS(int n, int k, int startPos, vect
阅读全文
摘要:滑动窗口(双指针) 要在字符串S里找出包含字符串T的所有字符的最小子串(注意只需要包含字符串T的所有字符),不需要子串就是T。 所以我们可以扫描一遍字符串S,找出一个满足条件包含字符串T的所有字符串子串,然后根据长度是否比之前记录的字符串长度小,更新最小子串。 扫描字符串S需要用到滑动窗口(双指针)
阅读全文
摘要:这道题的题意是,给出一个一维数组,数组中的元素只可能是0,1,2,分别表示红色、白色和蓝色。 我们需要做一个排序,使得0全部在数组前面,1在中间,2在后面。 (不过不能用sort函数) 方法一(常数空间,非一趟扫描) 可以用三个变量分别记录红色、白色和蓝色的出现次数,然后根据出现的次数,修改数组即可
阅读全文
摘要:这道题是要我们在一个二维数组里搜索某个元素target,找到了返回true,没找到返回false。 这个二维数组性质是,每一行都是升序的,且每一行的最后一个元素小于下一行的第一个元素。 都说升序和查找了,显然应该想到二分。 这题我最开始先按行二分,确定target(如果在数组里)所在的行,再对这一行
阅读全文
摘要:解法一(使用O(mn)空间) 可以开一个额外的二维数组,记录每个位置的元素是否已被访问过。 然后我们遍历原来的二维数组,只要没被访问过且元素为0,那么就将该元素所在的行和列的元素值置为0, 并且将这一行的所有元素都设置为已经访问过,以免之后的遍历碰到被置为0的元素也将那一行那一列的元素置为0. 这里
阅读全文
摘要:考虑用一个二维dp数组表示所需的最小操作次数。 dp[i][j]表示将word1的前i个字符转换为word2的前j个字符所需要的最少操作次数。 由于操作的顺序对于最后操作的结果没有影响,所以我们假设操作总是从word1的前面字符操作到word1的后面字符。 如果word1的第i个字符等于word2的
阅读全文
摘要:这题是要实现Linux里的类似pwd命令的功能,给出一串绝对地址,绝对地址里每两个"/"之间可能含有".","..","",/等, 这些特殊情况都需要判断。 思路是,遍历path字符串,对于每两个"/"之间的字符串temp,根据字符串内容考虑是否要压入一个额外的string数组strs中。 strs
阅读全文
摘要:由于每次只能跳一阶或者两阶台阶,所以要到达每一阶台阶的方案数都是到达上一阶台阶的方案数 和到达上上阶台阶的方案数之和。 如果我们用dp[i]表示到达第i阶台阶的方案数,那么可以得到递推公式dp[i] = dp[i - 1] + dp[i - 2]; 这就是一个斐波那契数列,递推边界是dp[0] =
阅读全文
摘要:这题是要用二分寻找一个数的平方根的整数部分。 当然顺序搜索也是可以的,但是由于搜索范围1 ~ sqrt(x)是有序的,所以显然可以用二分搜索。 这题由于是返回整数部分,所以二分的判断稍微要多写几行,如果一个数pow(mid, 2) < x, 但pow(mid + 1, 2) > x,这种情况下是返回
阅读全文

浙公网安备 33010602011771号