11 2019 档案
摘要:"题目链接" 【题解】 我们可以枚举这棵树的根节点在i处。 现在问题就变成。 1..i 1这i 1个节点组成的树和i+1..n这n i个节点组成的树的个数的问题了。 假设他们俩的结果分别是cnt1和cnt2. 那么答案就是cnt1 cnt2. 这显然是一个递归的问题。 因为4 5 6 7组成的二叉搜
阅读全文
摘要:"题目链接" 【题解】 我们在枚举下一个要取哪个数字的时候。 如 1112233 for (int i = start;istart且num[i]==num[i 1]. 那么我们就不应该再取这个num[i]了。 因为肯定在之前已经取过num[i 1]了。此时再取一个num[i]的话。所得到的方案肯定
阅读全文
摘要:"题目链接" 【题解】 把所有的"1"矩形分成m类。 第j类的矩形。他的右边界跟第j列紧靠。 那么。 我们设f[i][j]表示(i,j)这个点往左最长能延伸多少个数目的"1" 那么对于第j类的矩形。 我们会发现。问题转化为求一个侧着放的柱状图。 然后让你在其中找到最大面积的矩形。且要求紧贴着底面(也
阅读全文
摘要:"题目链接" 【题解】 维护一个单调递增的栈。 会发现栈内的第i个元素的前面一个(i 1)元素在原始的序列中的数字 都是要高于第i个元素的。(或者没有元素) 那么第i个元素往左最多可以扩展到第i 1个元素的右边。 那么它的右边界在哪里呢?当然是一直延伸到栈顶元素所在的位置了。 此时如果新加来的元素x
阅读全文
摘要:"题目链接" 【题解】 尺取法。 用l和r代表一个合法的覆盖子串。 我们不断地扩大右指针。 直到l..r包含T中的所有字母为止(重复的就要两次以上。) 然后我们可以尝试的让l++. 看看新的l..r是不是还是包含所有的字母。 如果是的话。 显然我们得到了一个更优的解。 而且可以肯定。 我们在递增l的
阅读全文
摘要:"题目链接" 【题解】 维护一个左边界l和一个右边界r 其中0..l 1都是'0' 而 r+1..n 1都是'2' 我们令i=l;i 【代码】
阅读全文
摘要:"题目链接" 【题解】 如果a[i][j]==0. 就把第i行的第一个数字置为0 然后把第j列的第一个数字置为0 最后再处理下每行第一个为0的行。每列第一个为0的列。 (第一行和第一列都得用同一个位置处理,所以会冲突。得额外定义一个变量,表示第1行是否需要全都置0) 然后把对应的行。列的元素全都置为
阅读全文
摘要:"题目链接" 【题解】 逆康托展开。 考虑康托展开的过程。 K = ∑v[i] (n i)! 其中v[i]表示在a[i+1..n]中比a[i]小的数字的个数 (也即未出现的数字中它排名第几(从0开始)) 那么我们在逆康托展开的时候,就可以通过直接除(n i)!得到每个数字的v[i]的值。 然后通过给
阅读全文
摘要:"题目链接" 【题解】 这题要分四种情况。 第一种。区间在所有区间的前面。 第二种。区间在所有区间的后面。 第三种。区间在某两个区间之间但是没有交集。 第四种。区间和某个区间产生了相交。 对于第四种枚举第一次产生相交的区间是哪一个。 然后往后尝试延伸。看看会不会合并更多区间。 【代码】
阅读全文
摘要:"题目链接" 【题解】 考虑每个位置它最后能接多少单位的水。 显然就是这个min(位置左边最高的位置,位置右边最高的位置) 当前这个位置的高度。 这就是这个位置最后水上涨的高度。 两个边界注意是不会储水的(都会掉到左边或者右边的边界外去). 每个位置左边最高的位置可以用DP很容易搞出来 【代码】
阅读全文
摘要:"题目链接" 【题解】 先明确一点假设给的数字有n个。 那么最后的答案最情况下就是n+1 首先我们先判断一下所给的数组里面有没有1 如果没有直接返回1 否则。 把数组中所有的范围超过n或者小于1的数字全都改成数字1 然后扫描一遍整个数组。 for(int i = 0;i 【代码】
阅读全文
摘要:"题目链接" 【题解】 回溯法搞一下。 用set和数组下标判重。 【代码】
阅读全文
摘要:"题目链接" 【题解】 就一傻逼模拟题 【代码】
阅读全文
摘要:"题目链接" 【题解】 还是那句话,想知道l或者r所在的数字的含义 就想想它最后一次执行的时候在干什么就行。 【代码】
阅读全文
摘要:"题目链接" 【题解】 二分某个数的上下界。 其实这个方法并不难。 只要你想清楚了二分最后一次执行的位置在什么地方就不难了。 【代码】
阅读全文
摘要:"题目链接" 【题解】 会发现旋转之后,假设旋转点是i 则0..i 1是递增有序的。然后i..len 1也是递增有序的。 且nums[i..len 1]nums[0] 所以我们可以把数组分成两段了。 怎么判断我们二分中点的时候是处在哪一段中的呢? 当然就是让nums[mid]和nums[0]比较一下
阅读全文
摘要:"题目链接" 【题解】 设dp[i]表示以第i个字符结尾的最长有效括号的长度。 显然只要考虑s[i]==')'的情况 则如果s[i 1]=='(',则dp[i] = dp[i 2]+2; 如果s[i 1]==')',那么我们现在要在i前面去给s[i]==')'这个右括号去找左括号。 那么显然我们要先
阅读全文
摘要:"题目链接" 【题解】 从右往左找第一个下降的位置i(即满足nums "i]最大的下标k,使得nums[k] nums[i" 注意一个性质(i+1..len 1)这一段是单调递减的了 然后swap(nums[k],nums[i]); 然后再把[i+1..len 1]这一段序列翻转一下。 就能得到ne
阅读全文
摘要:"题目链接" 【题解】 开个字典树记录下所有的单词。 然后注意题目的已知条件 每个单词的长度都是一样的。 这就说明不会出现某个字符串是另外一个字符串的前缀的情况(除非相同). 所以可以贪心地匹配(遇到什么字符就在字典树里面沿着边从根往下走就好). 假设给的单词的个数为len.(每个单词的长度都是L)
阅读全文
摘要:"题目链接" 【题解】 沙比提 【代码】
阅读全文
摘要:"题目链接" 【题解】 沙比提 【代码】
阅读全文
摘要:"题目链接" 【题解】 模拟就好。 就k个k个节点地翻转。 每个节点都把next域指向它前面那个节点 修改完之后把这个节点前面的那个节点的next域改成这一段的最后一个节点。 然后把这一段最左边的那个节点的next域修改为下一个区间的开始位置。 【代码】
阅读全文
摘要:"题目链接" 【题解】 简单的链表操作 【代码】
阅读全文
摘要:"题目链接" 【题解】 会归并排序吧? 就把这K个链表当成是K个数字就好。 然后做归并排序。 因为归并排序的时候本来就会有这么一个过程。 [l..mid]和[mid+1..r]这两段区间都是有序的了已经。 然后再把他们俩合并起来。 合并起来之后把这个链表直接放在这个区间的最左边那个位置就好 上一级的
阅读全文
摘要:"题目链接" 【题解】 一道傻逼回溯法。 每次都有两个选择,加个左括号。 加个右括号。无非加个判断啥时候不能加右括号了。 【代码】
阅读全文
摘要:"题目链接" 【题解】 就是归并排序的一趟合并操作。 新建个链表加在上面就好。(用原来的链表的头结点也没问题) 加个头结点会比较好操作一点。 返回的时候返回头结点的next域就行 【代码】
阅读全文
摘要:"题目链接" 【题解】 一道傻逼括号匹配题 【代码】
阅读全文
摘要:"题目链接" 【题解】 经典的一道题。 让p1指向链表的第一个元素。 让p2指向链表的第二个元素。 然后让他们俩同时往后移动。 直到p2到达链表的尾巴。 这时p1和p2之间总是隔了n 1个元素。 所以p1一定是倒数第n个元素。 记得加个虚拟的头结点方便删除操作(删掉了第一个数字的话)
阅读全文
摘要:"题目链接" 【题解】 两重循环枚举[i..j]这个区间 同时规定必取nums[i]和nums[j] 那么现在的问题就变成在下标为[i..j]这个区间的数字里面找两个数字使他们的和为target nums[i] nums[j]. 这个问题可以在O(N)的复杂度解决。 所以复杂度就是
阅读全文
摘要:"题目链接" 【题解】 用回溯法搞一下。 一搞就有~ 注意输入空串的时候别返回那个空串。。 【代码】
阅读全文
摘要:"题目链接" 【题解】 上一道题那个算法求三个数的和为0的时候,其实就是一个不断在逼近本题中x=0的情况。 那么就套用上面那道题的做法。 在逼近的时候,取个差值的最小值就好了。 【代码】
阅读全文
摘要:"题目链接" 【题解】 先把n个数字升序排个序。 然后枚举三元组最左边的那个数字是第i个数字。 之后用两个指针l,r移动来获取三元组的第2个和第3个数字。 (初始值,l=i+1,r = n 1); 如果a[i]+a[l]+a[r] 0 那么说明后面两个数字a[l]和a[r]太大了。 得让其中较大的那
阅读全文
摘要:"题目链接" 【题解】 二分最长前缀的长度。 然后暴力把第2..n个字符串和第1个字符串的前mid个字符匹配。 还有一种比较厉害的算法。 把这n个字符串加入到字典树当中去。 然后根节点到第一个有分支的节点路径上的点形成的字符串就是最长前缀了。 【代码】
阅读全文
摘要:"题目链接" 【题解】 就是上一题反过来的过程。 因为有说一般情况下后面的罗马数字是小于前面的罗马数字的。 如果前面的罗马数字小于后面的罗马数字了。 说明出现了4,9,40,90这些特殊情况。 那么就得判断一下下了。 直接用map把所有的罗马数字对应的数字都放进去。 然后就很好做啦。 写的时候遇到一
阅读全文
摘要:"题目链接" 【题解】 (涨知识了。。原来罗马数字是这么回事。。 把{1,4,5,9,10,40,50,90,100,400,500,900,1000}这些东西的罗马数字放在一个数组里面。 每次从大到小减。 减一个加上对应的罗马数字就好。 【代码】
阅读全文
摘要:"题目链接" 【题解】 双指针。 一开始l=0,r = len 1 然后不断往中间收缩。 如果发现h[l]h[r]同理 一开始想到的是一个nlogn的做法。 先从大到小排个序(按照高度)。 然后顺序枚举i 显然1..i这里面的板子组成的矩形的话,一定是以第i个板子的高度为准的(最小). 那么当前的任
阅读全文
摘要:"题目链接" 【题解】 看到这个 "题解" 写的代码。 就是加个备忘录法。优化一下暴力的做法。 匹配的时候如果遇到 号的话,就两种可能。不再考虑它前面一个字符了。 跳过这个 或者。或者继续用 前面那个字符匹配。 即dfs(i,j+2) 不和他匹配了 && (i和j能匹配且j+1是个 则继续复制一个和
阅读全文
摘要:"题目链接" 【题解】 还是要注意,取反的时候, 2^31 取反的话会爆掉Int。。(因为int的正数最多到2^31 1) 【代码】 cpp class Solution { public: bool isPalindrome(int x) { int f = 1; string s; s = ""
阅读全文
摘要:"题目链接" 【题解】 注意越界的处理就好 简单题 还有。。 正的 2^31不能由2^31取相反数得到,因为正的int最多到2^31 1 【代码】
阅读全文
摘要:"题目链接" 【题解】 没什么说的。 就注意一点。 可以在 10+n%10的时候。 顺便判断有没有溢出。 (直接用longlong可真是机制。。) 【代码】 cpp class Solution { public: int reverse(int x) { long long t = x; int
阅读全文
摘要:"题目链接" 【题解】 还想着模拟这个过程。然后发现只有行有用啊!... 那就建个rows大小的字符串数组存每行从左到右的字符就行啦。。 然后就是i从1变到n然后又变回1反复就好了。 最后把1..rows按顺序首尾连接在一起就行 【代码】 cpp class Solution { public: s
阅读全文
摘要:"题目链接" 描述 【题解】 "一个讲得比较好的博客地址" ; 感觉manacher算法的大概思路就是利用回文串左右对称的性质。 利用之前算出来的以某个点为中心的回文串。而当前要枚举的串被包括在其中。 则可以用左半部分的结果来获取右边当前的串的结果。 O(N) 当然也可以枚举中间点在哪个地方然后O(
阅读全文
摘要:"题目链接" 【题解】 假设在两个有序的序列中找第k小的数字。 那么我们先定位第一个序列中的第k/2个数字(不足则取最边上的那个数字)记下标为i1 然后定位第二个序列中的第k/2个数字(同样不足则取最边上的那个数字)记下标为i2 如果a[i1] 【代码】
阅读全文