搜索
搜索
abant2
世界上最菜的arcem
展开
-
leetcode 40 组合总和2 auto循环内踩坑
但是这题在笔试时,包括做力扣时老是错,主要是循环内自己设置的变量总是被跳过,比如ct,这种变量一定要设置在循环开始,防止被循环中各种奇怪的continue跳过,导致没有进行迭代。先上代码,此题并不难,是一个标准的偏序回溯问题,甚至比组合总和1还简单一些。用map存一下数目即可。原创 2023-02-15 16:07:50 · 211 阅读 · 0 评论 -
leetcode 46 全排列
全排列是难一些的dfs,每个元素都要过一遍,而且要按不同顺序,复杂度相对于传统dfs更高,要额外记录一个traversed,记录走过的距离,并且需要额外的for循环,每次遍历所有数,复杂度是很高的。原创 2023-02-10 23:45:25 · 136 阅读 · 0 评论 -
leetcode 240 单调矩阵搜索
此题和类似单调矩阵不太一样,每个小于target的行都有可能是。思路一:与普通矩阵类似,对每个小于target的行做二分查找class Solution {public: int bisect(vector<int> &v, int target) { int l = 0, r = v.size()-1; while(l<r) { int mid = ceil((l+r)/2.0);.原创 2021-07-28 14:04:27 · 171 阅读 · 0 评论 -
leetcode 74 类似单调矩阵 二分搜索
此题的矩阵和单调矩阵很像,是肯定要用二分的题目,先第一次二分,找到合适的左区间,第二次找到精确数值,要注意mid的判断,是核心。class Solution {public: int bisect(vector<int> &v, int target) { int l = 0, r = v.size()-1; while(l<r) { int mid = ceil((l+r)/2.0);.原创 2021-07-26 23:33:00 · 98 阅读 · 0 评论 -
leetcode 39 组合总和 偏序回溯
此题是经典的迷宫类题目,选定一个点后就不能再选了(要确定次数)。咱们可以通过限制树的遍历顺序来做,即不让后面的节点再访问到前面的节点,是一道经典的回溯题目。class Solution {int total;public: void dfs(vector<int>& cand, vector<vector<int>>& ans, vector<int> &path, int i, int sum) { .原创 2021-07-19 11:22:47 · 89 阅读 · 0 评论 -
有向图找环 拓扑排序
找环有几个问题,首先,是否要求找到所有的环?这个有点难,如果是完全图,那环太多了,只能暴力。所以,此题仅限于找一个环。平常加dp的话,用队列做还是很方便的,但是找环dfs是很在行的,此题用dfs记录路径即可。只需对原始的拓扑排序做一些修改即可。class Solution {map<int, vector<int>> v;public: int dfs(vector<int>& F, vector<int>&path, int原创 2021-07-03 20:33:00 · 597 阅读 · 0 评论 -
leetcode 617 合并二叉树
此题是一个比较巧妙的题,如果两边又一边为空,合并的就是另一边,这个是基本原理。代码如下,默认root1是要返回的,将root1的left和right都重置成最好的返回即可。/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode() : val(0), left(nullptr),原创 2021-06-26 17:35:20 · 77 阅读 · 1 评论 -
leetcode 104 二叉树的最大深度
正常的做法是dfs,一个一个遍历/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode() : val(0), left(nullptr), right(nullptr) {} * TreeNode(int x) : val(x), left(nullptr), righ原创 2021-06-26 16:57:58 · 66 阅读 · 0 评论 -
leetcode 101 对称二叉树 bfs+dfs
解法一:递归法每次按相反顺序插入细节:用!判断是否为空指针。/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode() : val(0), left(nullptr), right(nullptr) {} * TreeNode(int x) : val(x), lef原创 2021-06-26 16:31:53 · 106 阅读 · 0 评论 -
leetcode 547 dfs+并查集
是一个较为典型的并查集问题,也可以用dfs做。并查集用在在线算法上是最快的。解法一:dfsdfs搜索图,不需要回溯。无脑找就ok了。找k次,不断加ct就行。class Solution {int n;public: void dfs(vector<vector<int>>& isConnected, vector<int>& id, int i, int ct) { if(id[i] > 0)return;.原创 2021-06-17 16:05:15 · 147 阅读 · 0 评论 -
leetcode 1857 拓扑排序+dp
问题如上图所示,求每条路径的最大节点数目求max。做法是拓扑排序+dp。每个节点用上一个节点存的各个节点的数量进行更新,这个是核心。class Solution {map<int, vector<int>> adj;public: int largestPathValue(string colors, vector<vector<int>>& edges) { int n = colors.size(); .原创 2021-06-17 12:09:53 · 285 阅读 · 0 评论 -
leetcode 207 拓扑排序判断是否有环 回溯+bfs
解法一:dfs回溯法dfs解拓扑排序在无环情况下很方便,反向存边然后dfs即可。但要判断有没有环时,需要用回溯的思路:对每个点dfs,若无环,回溯时将这个点视为安全。具体操作时,存一个flag,dfs进入时让它为1,结束安全了变成-1.class Solution {map<int, vector<int>> m;map<int, int> F;public: int dfs(int n) { if(F[n] == -1)retu原创 2021-06-16 23:41:43 · 183 阅读 · 0 评论 -
最大团问题 Bron-Kerbosch算法
最大团即最大完全子图问题。正常的做法是,先从一个小集合开始,如果一个新点和这个集合每个元素都有一条边,那么这个新点就可以加到团中。Bron-Kerbosch算法的特点是,无需显示判断新点是否和原来的集合有边。R集合即为集合,P集合为搜索范围,由伪代码可见,每个点的邻居都要用交集处理。这样,只有所有人都有的邻居才能加入集合。X集合为不处理的点,如果不处理的点也是所有人的朋友,那就不是最大团(加入新点就不是团)。所以,此算法可以找到所有的最大团,很强。...原创 2021-05-09 20:25:42 · 2219 阅读 · 0 评论 -
topk问题终极解法 最坏O(N)
首先,按上图把数组分成很多个子数组,每个子数组有5个元素,分别排列,可以得到很多个按顺序排列的子数组。咱们找到这些数组中位数的中位数即为M,这个M是可以保证有相当一部分元素在其左边和右边,即对最坏选择点加了限制。之后就是常见的分治做法,交给子问题去做即可。下面为选择第k大的元素的代码:class Solution {public: int findKthLargest(vector<int>& nums, int k) { // 若少于5个,直接排序结束.原创 2021-04-09 14:37:56 · 273 阅读 · 0 评论 -
leetcode 1030 距离顺序排列矩阵单元格 桶排序+BFS 两种做法
思路:首先,很容易想到直接排序。但是排序复杂度那么高,排序是不可能排序的。这一看O(N)就能解决。简便的方法是用桶排序,由于是曼哈顿距离,比较好枚举。如果是几何距离的话,放到字典中还需要给字典的键排序,复杂度可能又要到O(NlogN)了。解法一:桶排序正规的桶排序是记录每个节点的位置,在以位置为下标的数组中记录。咱们的原理是一样的,只是可能每个桶有多个点。判断下最大距离,超出字典范围终止掉就好。class Solution: def allCellsDistOrder(self, R: int原创 2020-11-17 09:44:50 · 112 阅读 · 0 评论 -
leetcode 204 经典素数O(N)线性筛
解法一:暴力 O(NN\sqrt{N}N)看到一个数x,遍历[2, x]看是否整除,是最暴力的。此题还有个稍优雅解法,即遍历[2, x\sqrt{x}x]。由于一个数如果能被整除,那一定还有另一个数作为商,而这两个不可能都大于x\sqrt{x}x。直接这样做也会超时,可以只遍历奇数,并且保存存过的素数,只检查是否被素数整除即可,能勉强通过。from math import sqrtclass Solution: def countPrimes(self, n: int) -> in原创 2020-12-03 12:30:01 · 147 阅读 · 0 评论 -
leetcode 842 搜索剪枝
这个题还真挺简单的,值得记录的是这个题要求的数的范围在int内,但python的int函数其实是可以超过int范围的,所以咱们需要判断一下在(1<<31)-1范围内,另外,可以利用这一点,只搜索长度10以内的子串,是一个小的剪枝技巧。第二个点也是一个剪枝技巧,由于咱们需要先找到两个数,如果第一个数开头是0,那就不用搜索第二个数了。代码如下:class Solution: def splitIntoFibonacci(self, S: str) -> List[int]:原创 2020-12-08 09:48:03 · 218 阅读 · 0 评论 -
leetcode 1178 子集+状态压缩
这个题是比较难的一个题,每批输入给的单词数和谜题数都很多,O(N2N^2N2)是行不通的。由于题目中要求单词中字母的多样性要少于谜题,即匹配代表着单词中的字母在谜题中都出现。所以我们预存所有单词的表示到哈希表中,同时计算谜题的所有子集(谜题长度最多7位)。这样查找谜题,就会变快。这里有两个难点,一个是字母的表示,由于每个字母最多一次,不需要用质数,这里用bitmap即可。第二个是子集的获取,可以用递归的算法一行得出,这个也是很妙的地方。from collections import defaultdic原创 2021-02-26 13:31:12 · 178 阅读 · 0 评论 -
leetcode 1786 dijkstra + 记忆化搜索
这题还是有点意思的,算是个杂交题。先用dijkstra求出题目要求的单源最短路径,再用记忆化搜索优化dfs。这里dfs是可以用记忆化搜索优化的,将dfs的每一个状态含有的解计算好后放入dp数组,这样下次再遇到这个状态就可以直接返回。from heapq import *from collections import defaultdictclass Solution(object): def countRestrictedPaths(self, n, edges): """原创 2021-03-07 18:41:05 · 178 阅读 · 1 评论 -
leetcode 131 回文串预处理(记忆化+DP) + dfs搜索
此题判断子序列是否为回文串很重要,能省很多事情。一种方法就是用dp得出,另一种是记忆化搜索。得出结果后,可以用两个数组和传统dfs来得到所有可能的拆分结果。dp中,两个点要注意:正常状态要看左下角,即左索引+1,右索引-1的情况,所以需要我们从上往下建表,需要用到先i后j,用j,i进行索引,这个是个很强的技巧。第二个点是找到连续的相同的数,这点的处理也很棒。处理的规则是:只关注连续的两个。因为两个找到后,后续不管是三个四个都可以用左右扩张的方式得到。class Solution: def par原创 2021-03-07 23:36:19 · 156 阅读 · 0 评论 -
leetcode 132 记忆化搜索+dp
本题要求最少分割次数,首先要列出子序列是否为回文串的表,可以通过dp或者记忆化实现。之后要定义子结构,我们可以发现,当新字母来了时,我们要考虑有没有新的回文串,所以只要枚举所有新的回文串,再和dp数组加起来作比较即可。class Solution: def minCut(self, s: str) -> int: @cache def dfs(i, j): if i >= j: return 1 if s[原创 2021-03-08 09:23:08 · 152 阅读 · 0 评论 -
ZJ20 DFS回溯
这题一看人都麻了,完全没思路。无奈看了题解,发现这题完全是可以用dfs的,由于每次抽三张牌,导致dfs的深度最多只有4。咱们采用回溯的做法即可。由于咱们是以一个节点往后看,所以从1到9开始抽牌。from collections import Counterl = list(map(int, input().split(' ')))d = Counter(l)for i in range(1, 10): if i not in d: d[i] = 0def dfs(rema原创 2021-03-10 19:06:29 · 104 阅读 · 0 评论 -
剑指offer 12 回溯法
回溯法其实和dfs不太一样,就是每次遍历过的元素要弄回来,但也算是dfs吧,代码可以优化重复的部分,会更好。class Solution {public: int violate(vector<vector<char>>& board, int i, int j) { if(i >= 0 && j >= 0 && i<board.size() && j < board[原创 2021-03-15 15:42:43 · 95 阅读 · 0 评论