2024年4月刷题记录
2024年4月1日
【leetcode】2810. 故障键盘
题意:
你的笔记本键盘存在故障,每当你在上面输入字符
'i'
时,它会反转你所写的字符串。而输入其他字符则可以正常工作。给你一个下标从 0 开始的字符串
s
,请你用故障键盘依次输入每个字符。返回最终笔记本屏幕上输出的字符串。
2024年4月2日
【leetcode】894. 所有可能的真二叉树
题意:
给你一个整数
n
,请你找出所有可能含n
个节点的 真二叉树 ,并以列表形式返回。答案中每棵树的每个节点都必须符合Node.val == 0
。答案的每个元素都是一棵真二叉树的根节点。你可以按 任意顺序 返回最终的真二叉树列表。
真二叉树 是一类二叉树,树中每个节点恰好有
0
或2
个子节点。
2024年4月3日
【leetcode】1379. 找出克隆二叉树中的相同节点
题意:
给你两棵二叉树,原始树
original
和克隆树cloned
,以及一个位于原始树original
中的目标节点target
。其中,克隆树
cloned
是原始树original
的一个 副本 。请找出在树
cloned
中,与target
相同 的节点,并返回对该节点的引用(在 C/C++ 等有指针的语言中返回 节点指针,其他语言返回节点本身)。注意:你 不能 对两棵二叉树,以及
target
节点进行更改。只能 返回对克隆树cloned
中已有的节点的引用。
2024年4月4日
【leetcode】2192. 有向无环图中一个节点的所有祖先
题意:
给你一个正整数
n
,它表示一个 有向无环图 中节点的数目,节点编号为0
到n - 1
(包括两者)。给你一个二维整数数组
edges
,其中edges[i] = [from_i, to_i]
表示图中一条从from_i
到to_i
的单向边。请你返回一个数组
answer
,其中answer[i]
是第i
个节点的所有 祖先 ,这些祖先节点 升序 排序。如果
u
通过一系列边,能够到达v
,那么我们称节点u
是节点v
的 祖先 节点。
2024年4月5日
【leetcode】1026. 节点与其祖先之间的最大差值
题意:
给定二叉树的根节点
root
,找出存在于 不同 节点A
和B
之间的最大值V
,其中V = |A.val - B.val|
,且A
是B
的祖先。(如果 A 的任何子节点之一为 B,或者 A 的任何子节点是 B 的祖先,那么我们认为 A 是 B 的祖先)
2024年4月6日
【leetcode】1483. 树节点的第 K 个祖先
题意:
给你一棵树,树上有
n
个节点,按从0
到n-1
编号。树以父节点数组的形式给出,其中parent[i]
是节点i
的父节点。树的根节点是编号为0
的节点。树节点的第
k
个祖先节点是从该节点到根节点路径上的第k
个节点。实现
TreeAncestor
类:
TreeAncestor(int n, int[] parent)
对树和父数组中的节点数初始化对象。getKthAncestor(int node, int k)
返回节点node
的第k
个祖先节点。如果不存在这样的祖先节点,返回-1
。
2024年4月7日
【leetcode】1600. 王位继承顺序
题意:
一个王国里住着国王、他的孩子们、他的孙子们等等。每一个时间点,这个家庭里有人出生也有人死亡。
这个王国有一个明确规定的王位继承顺序,第一继承人总是国王自己。我们定义递归函数
Successor(x, curOrder)
,给定一个人x
和当前的继承顺序,该函数返回x
的下一继承人。Successor(x, curOrder): 如果 x 没有孩子或者所有 x 的孩子都在 curOrder 中: 如果 x 是国王,那么返回 null 否则,返回 Successor(x 的父亲, curOrder) 否则,返回 x 不在 curOrder 中最年长的孩子
比方说,假设王国由国王,他的孩子 Alice 和 Bob (Alice 比 Bob 年长)和 Alice 的孩子 Jack 组成。
- 一开始,
curOrder
为["king"]
.- 调用
Successor(king, curOrder)
,返回 Alice ,所以我们将 Alice 放入curOrder
中,得到["king", "Alice"]
。- 调用
Successor(Alice, curOrder)
,返回 Jack ,所以我们将 Jack 放入curOrder
中,得到["king", "Alice", "Jack"]
。- 调用
Successor(Jack, curOrder)
,返回 Bob ,所以我们将 Bob 放入curOrder
中,得到["king", "Alice", "Jack", "Bob"]
。- 调用
Successor(Bob, curOrder)
,返回null
。最终得到继承顺序为["king", "Alice", "Jack", "Bob"]
。通过以上的函数,我们总是能得到一个唯一的继承顺序。
请你实现
ThroneInheritance
类:
ThroneInheritance(string kingName)
初始化一个ThroneInheritance
类的对象。国王的名字作为构造函数的参数传入。void birth(string parentName, string childName)
表示parentName
新拥有了一个名为childName
的孩子。void death(string name)
表示名为name
的人死亡。一个人的死亡不会影响Successor
函数,也不会影响当前的继承顺序。你可以只将这个人标记为死亡状态。string[] getInheritanceOrder()
返回 除去 死亡人员的当前继承顺序列表。
2024年4月9日
【leetcode】2529. 正整数和负整数的最大计数
题意:
给你一个按 非递减顺序 排列的数组
nums
,返回正整数数目和负整数数目中的最大值。
- 换句话讲,如果
nums
中正整数的数目是pos
,而负整数的数目是neg
,返回pos
和neg
二者中的最大值。注意:
0
既不是正整数也不是负整数。
2024年4月10日
【leetcode】1702. 修改后的最大二进制字符串
题意:
给你一个二进制字符串
binary
,它仅有0
或者1
组成。你可以使用下面的操作任意次对它进行修改:
- 操作 1 :如果二进制串包含子字符串 "00" ,你可以用 "10" 将其替换。
- 比方说,
"**00**010" -> "**10**010"
- 操作 2 :如果二进制串包含子字符串 "10" ,你可以用 "01" 将其替换。
- 比方说,
"000**10**" -> "000**01**"
请你返回执行上述操作任意次以后能得到的 最大二进制字符串 。如果二进制字符串
x
对应的十进制数字大于二进制字符串y
对应的十进制数字,那么我们称二进制字符串x
大于二进制字符串y
。
2024年4月11日
【leetcode】1766. 互质树
题意:
给你一个
n
个节点的树(也就是一个无环连通无向图),节点编号从0
到n - 1
,且恰好有n - 1
条边,每个节点有一个值。树的 根节点 为 0 号点。给你一个整数数组
nums
和一个二维数组edges
来表示这棵树。nums[i]
表示第i
个点的值,edges[j] = [uj, vj]
表示节点uj
和节点vj
在树中有一条边。当
gcd(x, y) == 1
,我们称两个数x
和y
是 互质的 ,其中gcd(x, y)
是x
和y
的 最大公约数 。从节点
i
到 根 最短路径上的点都是节点i
的祖先节点。一个节点 不是 它自己的祖先节点。请你返回一个大小为
n
的数组ans
,其中ans[i]
是离节点i
最近的祖先节点且满足nums[i]
和nums[ans[i]]
是 互质的 ,如果不存在这样的祖先节点,ans[i]
为-1
。
2024年4月12日
【leetcode】2923. 找到冠军 I
题意:
一场比赛中共有
n
支队伍,按从0
到n - 1
编号。给你一个下标从 0 开始、大小为
n * n
的二维布尔矩阵grid
。对于满足0 <= i, j <= n - 1
且i != j
的所有i, j
:如果grid[i][j] == 1
,那么i
队比j
队 强 ;否则,j
队比i
队 强 。在这场比赛中,如果不存在某支强于
a
队的队伍,则认为a
队将会是 冠军 。返回这场比赛中将会成为冠军的队伍。
2024年4月13日
【leetcode】2924. 找到冠军 II
题意:
一场比赛中共有
n
支队伍,按从0
到n - 1
编号。每支队伍也是 有向无环图(DAG) 上的一个节点。给你一个整数
n
和一个下标从 0 开始、长度为m
的二维整数数组edges
表示这个有向无环图,其中edges[i] = [u_i, v_i]
表示图中存在一条从u_i
队到v_i
队的有向边。从
a
队到b
队的有向边意味着a
队比b
队 强 ,也就是b
队比a
队 弱 。在这场比赛中,如果不存在某支强于
a
队的队伍,则认为a
队将会是 冠军 。如果这场比赛存在 唯一 一个冠军,则返回将会成为冠军的队伍。否则,返回
-1
。
2024年4月14日
【leetcode】705. 设计哈希集合
题意:
不使用任何内建的哈希表库设计一个哈希集合(HashSet)。
实现
MyHashSet
类:
void add(key)
向哈希集合中插入值key
。bool contains(key)
返回哈希集合中是否存在这个值key
。void remove(key)
将给定值key
从哈希集合中删除。如果哈希集合中没有这个值,什么也不做。
2024年4月15日
【leetcode】147. 对链表进行插入排序
题意:
给定单个链表的头
head
,使用 插入排序 对链表进行排序,并返回 排序后链表的头 。
【leetcode】148. 排序链表
题意:
给你链表的头结点
head
,请将其按 升序 排列并返回 排序后的链表 。链表中节点的数目在范围
[0, 5*10^4]
内,且-10^5 <= Node.val <= 10^5
。要求在O(nlog n)
时间复杂度和常数级空间复杂度下,对链表进行排序。
【leetcode】706. 设计哈希映射
题意:
不使用任何内建的哈希表库设计一个哈希映射(HashMap)。
实现
MyHashMap
类:
MyHashMap()
用空映射初始化对象void put(int key, int value)
向 HashMap 插入一个键值对(key, value)
。如果key
已经存在于映射中,则更新其对应的值value
。int get(int key)
返回特定的key
所映射的value
;如果映射中不包含key
的映射,返回-1
。void remove(key)
如果映射中存在key
的映射,则移除key
和它所对应的value
。
2024年4月16日
【leetcode】924. 尽量减少恶意软件的传播
题意:
给出了一个由
n
个节点组成的网络,用n × n
个邻接矩阵图graph
表示。在节点网络中,当graph[i][j] = 1
时,表示节点i
能够直接连接到另一个节点j
。一些节点
initial
最初被恶意软件感染。只要两个节点直接连接,且其中至少一个节点受到恶意软件的感染,那么两个节点都将被恶意软件感染。这种恶意软件的传播将继续,直到没有更多的节点可以被这种方式感染。假设
M(initial)
是在恶意软件停止传播之后,整个网络中感染恶意软件的最终节点数。如果从
initial
中移除某一节点能够最小化M(initial)
, 返回该节点。如果有多个节点满足条件,就返回索引最小的节点。请注意,如果某个节点已从受感染节点的列表
initial
中删除,它以后仍有可能因恶意软件传播而受到感染。
2024年4月17日
【leetcode】928. 尽量减少恶意软件的传播 II
题意:
给定一个由
n
个节点组成的网络,用n x n
个邻接矩阵graph
表示。在节点网络中,只有当graph[i][j] = 1
时,节点i
能够直接连接到另一个节点j
。一些节点
initial
最初被恶意软件感染。只要两个节点直接连接,且其中至少一个节点受到恶意软件的感染,那么两个节点都将被恶意软件感染。这种恶意软件的传播将继续,直到没有更多的节点可以被这种方式感染。假设
M(initial)
是在恶意软件停止传播之后,整个网络中感染恶意软件的最终节点数。我们可以从
initial
中删除一个节点,并完全移除该节点以及从该节点到任何其他节点的任何连接。请返回移除后能够使
M(initial)
最小化的节点。如果有多个节点满足条件,返回索引 最小的节点 。
2024年4月18日
【leetcode】2007. 从双倍数组中还原原数组
题意:
一个整数数组
original
可以转变成一个 双倍 数组changed
,转变方式为将original
中每个元素 值乘以 2 加入数组中,然后将所有元素 随机打乱 。给你一个数组
changed
,如果change
是 双倍 数组,那么请你返回original
数组,否则请返回空数组。original
的元素可以以 任意 顺序返回。
2024年4月19日
【leetcode】128. 最长连续序列
题意:
给定一个未排序的整数数组
nums
,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。请你设计并实现时间复杂度为
O(n)
的算法解决此问题。
2024年4月20日
【leetcode】678. 有效的括号字符串
题意:
给你一个只包含三种字符的字符串,支持的字符类型分别是
'('
、')'
和'*'
。请你检验这个字符串是否为有效字符串,如果是有效字符串返回true
。有效字符串符合如下规则:
- 任何左括号
'('
必须有相应的右括号')'
。- 任何右括号
')'
必须有相应的左括号'('
。- 左括号
'('
必须在对应的右括号之前')'
。'*'
可以被视为单个右括号')'
,或单个左括号'('
,或一个空字符串。- 一个空字符串也被视为有效字符串。
【leetcode】39. 组合总和
题意:
给你一个 无重复元素 的整数数组
candidates
和一个目标整数target
,找出candidates
中可以使数字和为目标数target
的 所有 不同组合 ,并以列表形式返回。你可以按 任意顺序 返回这些组合。
candidates
中的 同一个 数字可以 无限制重复被选取 。如果至少一个数字的被选数量不同,则两种组合是不同的。对于给定的输入,保证和为
target
的不同组合数少于150
个。
2024年4月21日
【leetcode】216. 组合总和 III
题意:
找出所有相加之和为
n
的k
个数的组合,且满足下列条件:
- 只使用数字1到9
- 每个数字 最多使用一次
返回 所有可能的有效组合的列表 。该列表不能包含相同的组合两次,组合可以以任何顺序返回。
2024年4月22日
【leetcode】560. 和为 K 的子数组
题意:
给你一个整数数组
nums
和一个整数k
,请你统计并返回 该数组中和为k
的子数组的个数 。子数组是数组中元素的连续非空序列。
提示:
1 <= nums.length <= 2 * 10^4
-1000 <= nums[i] <= 1000
-10^7 <= k <= 10^7
【leetcode】230. 二叉搜索树中第K小的元素
题意:
给定一个二叉搜索树的根节点
root
,和一个整数k
,请你设计一个算法查找其中第k
个最小元素(从 1 开始计数)。进阶:如果二叉搜索树经常被修改(插入/删除操作)并且你需要频繁地查找第
k
小的值,你将如何优化算法?
【leetcode】77. 组合
题意:
给定两个整数
n
和k
,返回范围[1, n]
中所有可能的k
个数的组合。你可以按 任何顺序 返回答案。
【leetcode】40. 组合总和 II
题意:
给定一个候选人编号的集合
candidates
和一个目标数target
,找出candidates
中所有可以使数字和为target
的组合。
candidates
中的每个数字在每个组合中只能使用 一次 。注意:解集不能包含重复的组合。
【leetcode】377. 组合总和 Ⅳ
题意:
给你一个由 不同 整数组成的数组
nums
,和一个目标整数target
。请你从nums
中找出并返回总和为target
的元素组合的个数。题目数据保证答案符合 32 位整数范围。
2024年4月23日
【leetcode】1052. 爱生气的书店老板
题意:
有一个书店老板,他的书店开了
n
分钟。每分钟都有一些顾客进入这家商店。给定一个长度为n
的整数数组customers
,其中customers[i]
是在第i
分钟开始时进入商店的顾客数量,所有这些顾客在第i
分钟结束后离开。在某些时候,书店老板会生气。 如果书店老板在第
i
分钟生气,那么grumpy[i] = 1
,否则grumpy[i] = 0
。当书店老板生气时,那一分钟的顾客就会不满意,若老板不生气则顾客是满意的。
书店老板知道一个秘密技巧,能抑制自己的情绪,可以让自己连续
minutes
分钟不生气,但却只能使用一次。请你返回 这一天营业下来,最多有多少客户能够感到满意 。
【leetcode】1456. 定长子串中元音的最大数目
题意:
给你字符串
s
和整数k
。请返回字符串
s
中长度为k
的单个子字符串中可能包含的最大元音字母数。英文中的 元音字母 为(
a
,e
,i
,o
,u
)。
2024年4月24日
【leetcode】2385. 感染二叉树需要的总时间
题意:
给你一棵二叉树的根节点
root
,二叉树中节点的值 互不相同 。另给你一个整数start
。在第0
分钟,感染 将会从值为start
的节点开始爆发。每分钟,如果节点满足以下全部条件,就会被感染:
- 节点此前还没有感染。
- 节点与一个已感染节点相邻。
返回感染整棵树需要的分钟数。
2024年4月25日
【leetcode】2739. 总行驶距离
题意:
卡车有两个油箱。给你两个整数,
mainTank
表示主油箱中的燃料(以升为单位),additionalTank
表示副油箱中的燃料(以升为单位)。该卡车每耗费
1
升燃料都可以行驶10
km。每当主油箱使用了5
升燃料时,如果副油箱至少有1
升燃料,则会将1
升燃料从副油箱转移到主油箱。返回卡车可以行驶的最大距离。
注意:从副油箱向主油箱注入燃料不是连续行为。这一事件会在每消耗
5
升燃料时突然且立即发生。
2024年4月26日
【leetcode】1146. 快照数组
题意:
实现支持下列接口的「快照数组」- SnapshotArray:
SnapshotArray(int length)
- 初始化一个与指定长度相等的 类数组 的数据结构。初始时,每个元素都等于 0。void set(index, val)
- 会将指定索引index
处的元素设置为val
。int snap()
- 获取该数组的快照,并返回快照的编号snap_id
(快照号是调用snap()
的总次数减去1
)。int get(index, snap_id)
- 根据指定的snap_id
选择快照,并返回该快照指定索引index
的值。
2024年4月27日
【leetcode】2639. 查询网格图中每一列的宽度
题意:
给你一个下标从 0 开始的
m x n
整数矩阵grid
。矩阵中某一列的宽度是这一列数字的最大 字符串长度 。
- 比方说,如果
grid = [[-10], [3], [12]]
,那么唯一一列的宽度是3
,因为-10
的字符串长度为3
。请你返回一个大小为
n
的整数数组ans
,其中ans[i]
是第i
列的宽度。一个有
len
个数位的整数x
,如果是非负数,那么 字符串长度 为len
,否则为len + 1
。
2024年4月28日
【leetcode】2639. 查询网格图中每一列的宽度
题意:
给你一个整数
n
,以二进制字符串的形式返回该整数的 负二进制(base -2
)表示。注意,除非字符串就是
"0"
,否则返回的字符串中不能含有前导零。
2024年4月29日
【leetcode】1329. 将矩阵按对角线排序
题意:
矩阵对角线 是一条从矩阵最上面行或者最左侧列中的某个元素开始的对角线,沿右下方向一直到矩阵末尾的元素。例如,矩阵
mat
有6
行3
列,从mat[2][0]
开始的 矩阵对角线 将会经过mat[2][0]
、mat[3][1]
和mat[4][2]
。给你一个
m * n
的整数矩阵mat
,请你将同一条 矩阵对角线 上的元素按升序排序后,返回排好序的矩阵。
2024年4月30日
【leetcode】2798. 满足目标工作时长的员工数目
题意:
公司里共有
n
名员工,按从0
到n - 1
编号。每个员工i
已经在公司工作了hours[i]
小时。公司要求每位员工工作 至少
target
小时。给你一个下标从 0 开始、长度为
n
的非负整数数组hours
和一个非负整数target
。请你用整数表示并返回工作至少
target
小时的员工数。