- 博客(54)
- 收藏
- 关注
原创 LC235 LC236 LCA最近公共祖先
树的题目肯定是要用递归来做的, 但是初看此题,很容易没有思路我们还是要把它分成root, root->left, root->right来看,来分析怎么获得p/q所在的子树的位置,到底是root->left还是root->right那么对于二叉搜索树我们就是直接使用val来进行比较,即可判断p/q的位置,而普通二叉树需要我们根据更深层的root->left,root->right的返回值是否为空来判断p/q的位置。
2024-10-30 23:00:00
359
1
原创 857.雇佣K名工人的最低成本
所以按照quaility升序排序,这样越往后其实sum这一项就越大,因此我们要让max变小,也就是不选max对应的那一项,选第二大...的人来安排,这里的最贵指的就是cost[i] = wage[i] *1.0 / quality[i] 最高.题目说的其实是有点乱的,所以我们可能抓不住重点,甚至都不太清楚规则,比如 eg.),优化的思路也和 lc 2398类似(详见我的题解), 简单来说就是。而且因为不要求连续 ,所以我们可以使用sort进行优化,(btw.
2024-05-02 11:50:55
100
原创 337. 打家劫舍 III 树上最大独立集
那么如果当前节点抢了,左右孩子就都不能抢了,而如果当前节点不抢,那么就看是抢左右节点好还是不抢好来判断.最后递归到根节点就是返回 max (dfs(root,false),dfs(root,true))dfs(node,rob) 表示对于当前node节点,抢了true或者不抢false的最高金额.在打家劫舍中,我们是使用dp[i]记录当前的最大值,如果上一家刚抢过,就返回dp[i-2]而对于这个题目,我们对每个节点记录两个状态,就是抢和没抢的最大值。这个代码也是灵神的记忆化dfs的模板,可以借鉴学习一下。
2024-04-28 22:00:00
196
原创 739.每日温度
单调栈是一种思想,是用来维护某种限制下的最大最小值,通常只是维护一个最大值或者最小值,不能为了用单调栈而用. -----------无名氏最简单的思想当然是直接从每一个i开始往后寻找下一个更大的元素,但是这种思想是O(n^2),对1e5的数据会超时我们使用单调栈优化,也就是用单调栈这种数据结构保存当前的最大值。
2024-04-28 22:00:00
239
原创 968.监控二叉树 树上最小支配集
一个被支配的节点只会有三种状态1.它本身有摄像头2.他没有摄像头, 但是它的父节点有摄像头3.他没有摄像头, 但是它的子节点有摄像头我们 dfs(node,state) 记录在node节点时(以node为根的子树),状态为state下的所有最小摄像头// 本身有摄像头就看左右孩子了// 本身没有摄像头, 左右孩子不能是2// 本身没有摄像头, 要靠子节点保障,同样左右孩子不能是2,而且至少有一个1边界条件怎么思考呢:也就是叶子节点的不应该是用nullptr保障 ,
2024-04-28 22:00:00
622
原创 LCR 184.设计自助结算系统
而remove会比较有趣,他每次是返回数组的当前元素,而且如果这个元素等于队头,那么说明单调队列要pop_front(), 而且dq里面的元素是vector里面的元素的。get_max就返回队头即可, add就在加入之前删除掉所有小于他的元素即可,等于的元素应该放在不删除.不然就会提前出现-1。这个题,我们需要单调队列来维护当前的最大值,达到O(1)的时间复杂度,同时使用一个数组记录当前出现的元素。所以每次删除一定是正确的。
2024-04-28 22:00:00
295
原创 2944.购买水果需要的最少金币数
买了下标 i 的水果, 可以免费获得 (i+1) 个水果dp[i][0] 表示 获得 0...i 的水果需要的 最少金币(i是免费获得的)dp[i][1] 表示 获得 0...i 的水果需要的 最少金币(i是购买获得的)dp[i][0] = min(dp[j][1]) j=i/2...i-1 // dp[i][0] : i要是想免费获得,必须是之前买了一个水果。
2024-04-28 22:00:00
329
原创 1438.绝对差不超过限制的最长连续子数组
只有当left等于某一个dq.front()的时候,才把它pop_front().这就使得对应相同的元素,我们只需要保留一个就行,也就是说在队尾遇见了相同的元素,我们可以直接加入,也可以删除相同的再加入.开始的时候我一直担心pop_back这里会影响left, 也就是说为了维护单调性会删除错误的元素,但是后来我发现其实不会,因为它删除的元素都是在left边界之前的, 不会影响left。
2024-04-28 22:00:00
191
原创 1499.满足不等式的最大值
这个题目的第一步的转化很坑,也就是说我们要先想到 i<j时, yi+yj+|xi-xj| = (xj+yj) + (yi-xi)那么也就是对于一个j,求所有的 i(i<j) 使得 (yi-xi)最大,所以我们可以套用模板一,也就是。
2024-04-28 22:00:00
262
原创 862.和至少为K的最短子数组
其实这样的对于的题目,都可以想一想单调队列首先想一想暴力解, 其实对于很多问题我们都可以先想一想暴力解,这是很好的启发思路的方式,之后再进行优化,或者改进算法,或者使用更好的数据结构,
2024-04-28 22:00:00
280
原创 4.寻找两个正序数组的中位数
我们找一个i,把nums1分成两部分, nums1[0...i-1](i个)和 nums[i...m-1](m-i个),我们找一个j,同样把nums2分成两部分,nums2[0...j-1](j个)和 nums[j...n-1](n-j个),如果能够使得前面(i+j) 个 和后面(m-i+n-j)个满足中位数的定义,就是了如果m+n是偶数,我们就找 i+j=m-i + n-j 同时使得如果m+n是奇数,我们就找 i+j=m-i + n-j +1 同时使得统一一下就是 i+j = (n+m+1)/2。
2024-04-28 22:00:00
2725
原创 3122.使矩阵满足条件的最少操作次数
显然根据题意我们需要让每一列都相同,但是相邻列不能选择同一种数字,观察到数据nums[i]介于0-9,我们就以此为突破口.入口是dfs(n-1,10);使用10是表示没有上一个,取0-9均可。表示 i 对应的那一列选择k的话, 再去判断i-1对应的那一列的元素。代码如下: 这里写的是 记忆化回溯 ,可以自行改成二维dp。周赛第三题,知道要用动态规划,但是不知道怎么回到子问题。
2024-04-27 19:02:19
381
原创 (回溯)记忆化搜索和dp
记忆化搜索之后 我们可以发现 每个新节点依赖的都是上一个状态和上上一个状态。,那么干脆去掉递归中的递 ,只保留递归中的归,也就是从下往上走,那么就是 dp 了。比如 采用子集类回溯问题中的核心思想-> 选或不选 或者 选哪个。首先很多动态规划问题都可以采用 回溯 的思想。回溯主要思想就是把 一个大问题分解成小问题。灵神 的 回溯改递归思路。
2024-04-22 22:00:00
242
原创 210. 课程表 II
入度为0进入队列在循环中每次 从队列中移出一个元素并把它指向的元素入度减一 同样的入度为0进入队列当队列为空 或者 次数达到numCourse 退出循环。
2024-04-13 22:00:00
415
原创 sort和priority_queue的自定义比较函数
sort重载运算符对于a,b来说 a<b是升序 ,sort重载运算符对于a,b来说 a<b是升序 ,但是对于priority_queue就是a<b是降序。
2024-03-30 22:00:00
309
原创 二分法 与 ccfcsp 垦田计划202303-2
因为在上一个问题中,我们需在找不到的时候,返回-1, 所以使用 left<=right 这个条件判断当前是不是区间,如果不是,说明没找到。注意到对于 day 在 [k , max (ti) i=1,2,3...] 存在一个天数 使得前面都实现不了 后面都可以实现,满足二分法的应用。而在这个问题中,我们是使用left==right跳出循环,夹出位置,也就是如果存在第一个大于等于target的位置,那么他就是left/right。满足条件的时候取到mid而不是mid-1或者mid+1,这是逻辑决定的。
2024-03-30 22:00:00
510
原创 41. 缺失的第一个正数
一个很简单的思路是说我们把nums[i] 放在一个map里面 ,然后找一找 没有出现的最小正整数但是这样空间复杂度O(n)
2024-03-09 22:00:00
303
原创 76.最小覆盖子串
注意每次 needCount为0 需要选择性更新之后, 需要 l ++ 以此跳过最后一个 t 中的字母使得needCount > 0 再次进入内层循环。这里我们引入一个变量 needCount 表示当前左边界到右边界所需要的 t 中字母的个数 也就是 need中正数之和.min_l 和 min_r 表示 当前记录下的最小的字母的左右边界。这里有个难点是判断什么时候右边界停止, 什么时候左边界不可缩进,我们使用need这个map记录左边界到右边界中。l 和 r 表示当前的左右边界。
2024-03-09 22:00:00
230
原创 56.合并区间
而如果 右边界小于下一个的左边界,直接跳过,从下一个进入循环。在这个基础上,他证明了这种情况下的题解的正确性,详见。把元素按照左边界升序排列, 然后在循环中观察右边界。官方题解是认为 如果说在我们的做法下。存在两个本来能够合并的元素但是没有合并。他们中间有一个元素阻止了这个合并。这个题我完全是跟着感觉做的。
2024-03-09 22:00:00
296
原创 189.轮转数组
所以我们可以先反转一次使得最后的k个元素到首部 ,之后对[0,k mod n−1] 区间的元素和 [k mod n,n−1] 分别再反转一次就得到答案.
2024-03-09 22:00:00
391
原创 最完整的IDEA算法加解密详解
K1-K6都是密钥,因此一共需要6*8+4 = 52组密钥,密钥是128bit,先取得第一组6个(96bit),然后每次循环左移25位,再取下一组的96bit,再循环左移25bit,最后一次取4个(64bit)· 当轮数为 2,...,8 时,取相应的第 3 个和第 2 个的子密钥的2^16的加密逆元。第 i(1-9) 轮的解密的密钥的前 4 个子密钥由加密过程中第 10-i 轮的前 4 个子密钥得出。· 第 5 和第 6 个密钥是第9-i轮的第5和第6个密钥。p1 是最高16bit位。
2024-03-07 18:00:00
1692
原创 15. 三数之和
两数和是求两个数他们的下标使得和达到target, 简便做法是设计一个map,在遍历之前寻找map里面存在target - nums[i] 的数据,从而避免一个数被重复计算。2.a和b可以相等, 也就是second > first + 1 的时候才去检验 nums[second] == nums[second-1]?因为不重复的本质就是 在给定 a<=b<=c的情况下,只能有这样形式的一组数据 -> 排序。1.对于 a(或者b或者c) 的更新,必须是严格大于上一次的数据 ,不能和上一次相等。
2024-03-06 22:00:00
468
原创 438.找到字符串中所有字母异位词
很简单的一个题,看数据量到达了10^4,应该是一个代码复杂一点的O(n)的时间复杂度。之后把p的字符作为+,s的字符记为-,当数组26为全0标志着 应该把该索引加入。先特判 如果p.size() > s.size() 返回空。在遇到下一个s的字符的时候, 减减。对于被滑出s的字符 , 加加。想到滑动窗口这个题目就基本解决了,
2024-03-06 22:00:00
152
原创 128.最大连续序列
因为只有每一个连续序列的首元素才可能进入内循环,所以每一个元素最多只会进入一次内循环,时间复杂度是O(n)对于每一个x-1不存在的x,都是一个可能的潜力股,需要接着去寻找 ++x。那么很自然的, 我们使用set进行元素的查找。这个题目的最大的难点在于想到。
2024-03-05 22:00:00
186
1
原创 字母异位词分组
有时候对于某一个样例 测试通过了, 而没通过提交 可能是数组未初始化的原因,导致重复提交的时候某一次初始化不是0。使用sort可以原地字符数组排序。
2024-03-05 11:18:09
207
1
原创 【无标题】
2.示例5表明nums[i]可能很大,应注意先把每一个num[i]对p取余代替原来的num[i],不然可能会超过1<<31-1,其实就算进行了取余在进行前缀和+=时,也仍然可能超过1<<31-1,我们需要把sum[i]+=sum[i-1]换成 sum[i]=(sum[i]+sum[i-1])%p.3.对于下标从0开始的子序列,无法使用上述公式包含,除非我们加入一个map[0]=-1,但是这里我们选择直接进行一次从0开始的遍历寻找sum[i]==remainder的i下标就好。4.怎么hash 要不要覆盖。
2024-03-05 11:10:59
264
1
原创 CLion链接gmp(c++大数库)
先下一个msys2(win下的unix窗口),再使用。gmp的下载可以直接网上找也可以像我一样。使用dev和vs安装gmp很麻烦,只用修改cmakelist.txt。我这里不详细,主要说说clion。使用CLion很容易,一次过。
2023-12-25 23:15:17
695
1
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人