;
-};
+function removeSubfolders(folder: string[]): string[] {
+ const trie = new Trie();
+ for (let i = 0; i < folder.length; ++i) {
+ trie.insert(i, folder[i]);
+ }
+ return trie.search().map(i => folder[i]);
+}
diff --git a/solution/1200-1299/1233.Remove Sub-Folders from the Filesystem/Solution3.go b/solution/1200-1299/1233.Remove Sub-Folders from the Filesystem/Solution3.go
deleted file mode 100644
index 9a5f248168d9d..0000000000000
--- a/solution/1200-1299/1233.Remove Sub-Folders from the Filesystem/Solution3.go
+++ /dev/null
@@ -1,46 +0,0 @@
-type Trie struct {
- children map[string]*Trie
- fid int
-}
-
-func newTrie() *Trie {
- return &Trie{map[string]*Trie{}, -1}
-}
-
-func (this *Trie) insert(fid int, f string) {
- node := this
- ps := strings.Split(f, "/")
- for _, p := range ps[1:] {
- if _, ok := node.children[p]; !ok {
- node.children[p] = newTrie()
- }
- node = node.children[p]
- }
- node.fid = fid
-}
-
-func (this *Trie) search() (ans []int) {
- var dfs func(*Trie)
- dfs = func(root *Trie) {
- if root.fid != -1 {
- ans = append(ans, root.fid)
- return
- }
- for _, child := range root.children {
- dfs(child)
- }
- }
- dfs(this)
- return
-}
-
-func removeSubfolders(folder []string) (ans []string) {
- trie := newTrie()
- for i, f := range folder {
- trie.insert(i, f)
- }
- for _, i := range trie.search() {
- ans = append(ans, folder[i])
- }
- return
-}
\ No newline at end of file
diff --git a/solution/1200-1299/1236.Web Crawler/README.md b/solution/1200-1299/1236.Web Crawler/README.md
index b8576d0677d3b..02c0e243a2ce2 100644
--- a/solution/1200-1299/1236.Web Crawler/README.md
+++ b/solution/1200-1299/1236.Web Crawler/README.md
@@ -19,22 +19,22 @@ tags:
-给定一个链接 startUrl
和一个接口 HtmlParser
,请你实现一个网络爬虫,以实现爬取同 startUrl
拥有相同 主机名 的全部链接。
+给定一个网址 startUrl
和一个接口 HtmlParser
,请你实现一个网络爬虫,以实现爬取同 startUrl
拥有相同 主机名 的全部链接。
-该爬虫得到的全部链接可以 任何顺序 返回结果。
+该爬虫得到的全部网址可以 任何顺序 返回结果。
你的网络爬虫应当按照如下模式工作:
- - 自链接
startUrl
开始爬取
- - 调用
HtmlParser.getUrls(url)
来获得链接url
页面中的全部链接
+ - 自页面
startUrl
开始爬取
+ - 调用
HtmlParser.getUrls(url)
来获得给定 url
网址中的全部链接
- 同一个链接最多只爬取一次
- - 只输出 域名 与
startUrl
相同 的链接集合
+ - 只浏览 域名 与
startUrl
相同 的链接集合

-如上所示的一个链接,其域名为 example.org
。简单起见,你可以假设所有的链接都采用 http协议 并没有指定 端口。例如,链接 http://leetcode.com/problems
和 http://leetcode.com/contest
是同一个域名下的,而链接 http://example.org/test
和 http://example.com/abc
是不在同一域名下的。
+如上所示的一个网址,其域名为 example.org
。简单起见,你可以假设所有的网址都采用 http协议 并没有指定 端口。例如,网址 http://leetcode.com/problems
和 http://leetcode.com/contest
是同一个域名下的,而网址 http://example.org/test
和 http://example.com/abc
是不在同一域名下的。
HtmlParser
接口定义如下:
@@ -46,7 +46,7 @@ interface HtmlParser {
下面是两个实例,用以解释该问题的设计功能,对于自定义测试,你可以使用三个变量 urls
, edges
和 startUrl
。注意在代码实现中,你只可以访问 startUrl
,而 urls
和 edges
不可以在你的代码中被直接访问。
-注意:将尾随斜线“/”的相同 URL 视为不同的 URL。例如,“http://news.yahoo.com” 和 “http://news.yahoo.com/” 是不同的域名。
+注意:将尾随斜线“/”的相同网址视为不同的网址。例如,“http://news.yahoo.com” 和 “http://news.yahoo.com/” 是不同的网址。
diff --git a/solution/1200-1299/1238.Circular Permutation in Binary Representation/README_EN.md b/solution/1200-1299/1238.Circular Permutation in Binary Representation/README_EN.md
index 57a0b48ed9325..f3d3a209aa212 100644
--- a/solution/1200-1299/1238.Circular Permutation in Binary Representation/README_EN.md
+++ b/solution/1200-1299/1238.Circular Permutation in Binary Representation/README_EN.md
@@ -23,35 +23,53 @@ tags:
Given 2 integers n
and start
. Your task is return any permutation p
of (0,1,2.....,2^n -1)
such that :
- p[0] = start
- p[i]
and p[i+1]
differ by only one bit in their binary representation.
- p[0]
and p[2^n -1]
must also differ by only one bit in their binary representation.
+
+ p[0] = start
+
+ p[i]
and p[i+1]
differ by only one bit in their binary representation.
+
+ p[0]
and p[2^n -1]
must also differ by only one bit in their binary representation.
+
+
Example 1:
+
Input: n = 2, start = 3
+
Output: [3,2,0,1]
+
Explanation: The binary representation of the permutation is (11,10,00,01).
+
All the adjacent element differ by one bit. Another valid permutation is [3,1,0,2]
+
Example 2:
+
Input: n = 3, start = 2
+
Output: [2,6,7,5,4,0,1,3]
+
Explanation: The binary representation of the permutation is (010,110,111,101,100,000,001,011).
+
+
Constraints:
- 1 <= n <= 16
- 0 <= start < 2 ^ n
+
+ 1 <= n <= 16
+
+ 0 <= start < 2 ^ n
+
diff --git a/solution/1200-1299/1256.Encode Number/README_EN.md b/solution/1200-1299/1256.Encode Number/README_EN.md
index 8793661958481..43b8d3ed61ded 100644
--- a/solution/1200-1299/1256.Encode Number/README_EN.md
+++ b/solution/1200-1299/1256.Encode Number/README_EN.md
@@ -27,25 +27,35 @@ tags:

+
Example 1:
+
Input: num = 23
+
Output: "1000"
+
Example 2:
+
Input: num = 107
+
Output: "101100"
+
+
Constraints:
- 0 <= num <= 10^9
+
+ 0 <= num <= 10^9
+
diff --git a/solution/1200-1299/1257.Smallest Common Region/README.md b/solution/1200-1299/1257.Smallest Common Region/README.md
index f9a73717dfc2d..9f9d29a65c437 100644
--- a/solution/1200-1299/1257.Smallest Common Region/README.md
+++ b/solution/1200-1299/1257.Smallest Common Region/README.md
@@ -23,14 +23,14 @@ tags:
-给你一些区域列表 regions
,每个列表的第一个区域都包含这个列表内所有其他区域。
+给你一些区域列表 regions
,每个列表的第一个区域都 直接 包含这个列表内所有其他区域。
+
+如果一个区域 x
直接包含区域 y
,并且区域 y
直接包含区域 z
,那么说区域 x
间接 包含区域 z
。请注意,区域 x
也 间接 包含所有在 y
中 间接 包含的区域。
很自然地,如果区域 x
包含区域 y
,那么区域 x
比区域 y
大。同时根据定义,区域 x
包含自身。
给定两个区域 region1
和 region2
,找到同时包含这两个区域的 最小 区域。
-如果给定区域 r1
,r2
和 r3
,使得 r1
包含 r3
,那么数据保证 r2
不会包含 r3
。
-
数据同样保证最小区域一定存在。
diff --git a/solution/1200-1299/1257.Smallest Common Region/README_EN.md b/solution/1200-1299/1257.Smallest Common Region/README_EN.md
index d5b52f58e36c7..2085a7c0a74a4 100644
--- a/solution/1200-1299/1257.Smallest Common Region/README_EN.md
+++ b/solution/1200-1299/1257.Smallest Common Region/README_EN.md
@@ -23,13 +23,13 @@ tags:
-You are given some lists of regions
where the first region of each list includes all other regions in that list.
+You are given some lists of regions
where the first region of each list directly contains all other regions in that list.
-Naturally, if a region x
contains another region y
then x
is bigger than y
. Also, by definition, a region x
contains itself.
+If a region x
contains a region y
directly, and region y
contains region z
directly, then region x
is said to contain region z
indirectly. Note that region x
also indirectly contains all regions indirectly containd in y
.
-Given two regions: region1
and region2
, return the smallest region that contains both of them.
+Naturally, if a region x
contains (either directly or indirectly) another region y
, then x
is bigger than or equal to y
in size. Also, by definition, a region x
contains itself.
-If you are given regions r1
, r2
, and r3
such that r1
includes r3
, it is guaranteed there is no r2
such that r2
includes r3
.
+Given two regions: region1
and region2
, return the smallest region that contains both of them.
It is guaranteed the smallest region exists.
@@ -65,6 +65,7 @@ region2 = "New York"
region1 != region2
regions[i][j]
, region1
, and region2
consist of English letters.
The input is generated such that there exists a region which contains all the other regions, either directly or indirectly.
+ A region cannot be directly contained in more than one region.
diff --git a/solution/1200-1299/1258.Synonymous Sentences/README.md b/solution/1200-1299/1258.Synonymous Sentences/README.md
index 2b00239e3e600..c5efea5ae8214 100644
--- a/solution/1200-1299/1258.Synonymous Sentences/README.md
+++ b/solution/1200-1299/1258.Synonymous Sentences/README.md
@@ -5,6 +5,7 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/1200-1299/1258.Sy
rating: 1847
source: 第 13 场双周赛 Q3
tags:
+ - 排序
- 并查集
- 数组
- 哈希表
diff --git a/solution/1200-1299/1258.Synonymous Sentences/README_EN.md b/solution/1200-1299/1258.Synonymous Sentences/README_EN.md
index 5e6126ae5a0c2..849c4d294e764 100644
--- a/solution/1200-1299/1258.Synonymous Sentences/README_EN.md
+++ b/solution/1200-1299/1258.Synonymous Sentences/README_EN.md
@@ -5,6 +5,7 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/1200-1299/1258.Sy
rating: 1847
source: Biweekly Contest 13 Q3
tags:
+ - Sort
- Union Find
- Array
- Hash Table
diff --git a/solution/1200-1299/1290.Convert Binary Number in a Linked List to Integer/README.md b/solution/1200-1299/1290.Convert Binary Number in a Linked List to Integer/README.md
index 64d18981736ca..b31a8a0daf1b6 100644
--- a/solution/1200-1299/1290.Convert Binary Number in a Linked List to Integer/README.md
+++ b/solution/1200-1299/1290.Convert Binary Number in a Linked List to Integer/README.md
@@ -23,38 +23,24 @@ tags:
请你返回该链表所表示数字的 十进制值 。
+最高位 在链表的头部。
+
示例 1:
-
+
-输入:head = [1,0,1]
+
+输入:head = [1,0,1]
输出:5
解释:二进制数 (101) 转化为十进制数 (5)
示例 2:
-输入:head = [0]
-输出:0
-
-
-示例 3:
-
-输入:head = [1]
-输出:1
-
-
-示例 4:
-
-输入:head = [1,0,0,1,0,0,1,1,1,0,0,0,0,0,0]
-输出:18880
-
-
-示例 5:
-
-输入:head = [0,0]
+
+输入:head = [0]
输出:0
@@ -76,11 +62,11 @@ tags:
### 方法一:遍历链表
-我们用变量 `ans` 记录当前的十进制值,初始值为 $0$。
+我们用变量 $\textit{ans}$ 记录当前的十进制值,初始值为 $0$。
-遍历链表,对于每个结点,将 `ans` 左移一位,然后再或上当前结点的值。遍历结束后,`ans` 即为十进制值。
+遍历链表,对于每个结点,将 $\textit{ans}$ 左移一位,然后再或上当前结点的值。遍历结束后,$\textit{ans}$ 即为十进制值。
-时间复杂度 $O(n)$,空间复杂度 $O(1)$。其中 $n$ 为链表的长度。
+时间复杂度 $O(n)$,其中 $n$ 为链表的长度。空间复杂度 $O(1)$。
@@ -212,12 +198,11 @@ function getDecimalValue(head: ListNode | null): number {
// }
// }
impl Solution {
- pub fn get_decimal_value(head: Option>) -> i32 {
+ pub fn get_decimal_value(mut head: Option>) -> i32 {
let mut ans = 0;
- let mut cur = &head;
- while let Some(node) = cur {
+ while let Some(node) = head {
ans = (ans << 1) | node.val;
- cur = &node.next;
+ head = node.next;
}
ans
}
@@ -247,6 +232,31 @@ var getDecimalValue = function (head) {
};
```
+#### C#
+
+```cs
+/**
+ * Definition for singly-linked list.
+ * public class ListNode {
+ * public int val;
+ * public ListNode next;
+ * public ListNode(int val=0, ListNode next=null) {
+ * this.val = val;
+ * this.next = next;
+ * }
+ * }
+ */
+public class Solution {
+ public int GetDecimalValue(ListNode head) {
+ int ans = 0;
+ for (; head != null; head = head.next) {
+ ans = ans << 1 | head.val;
+ }
+ return ans;
+ }
+}
+```
+
#### PHP
```php
@@ -267,13 +277,12 @@ class Solution {
* @return Integer
*/
function getDecimalValue($head) {
- $rs = [];
- while ($head != null) {
- array_push($rs, $head->val);
+ $ans = 0;
+ while ($head !== null) {
+ $ans = ($ans << 1) | $head->val;
$head = $head->next;
}
- $rsStr = implode($rs);
- return bindec($rsStr);
+ return $ans;
}
}
```
diff --git a/solution/1200-1299/1290.Convert Binary Number in a Linked List to Integer/README_EN.md b/solution/1200-1299/1290.Convert Binary Number in a Linked List to Integer/README_EN.md
index 3e49f84db6367..5d6aaab02c5ac 100644
--- a/solution/1200-1299/1290.Convert Binary Number in a Linked List to Integer/README_EN.md
+++ b/solution/1200-1299/1290.Convert Binary Number in a Linked List to Integer/README_EN.md
@@ -56,7 +56,13 @@ tags:
-### Solution 1
+### Solution 1: Traverse the Linked List
+
+We use a variable $\textit{ans}$ to record the current decimal value, with an initial value of $0$.
+
+Traverse the linked list. For each node, left-shift $\textit{ans}$ by one bit, then perform a bitwise OR with the current node's value. After traversal, $\textit{ans}$ is the decimal value.
+
+The time complexity is $O(n)$, where $n$ is the length of the linked list. The space complexity is $O(1)$.
@@ -188,12 +194,11 @@ function getDecimalValue(head: ListNode | null): number {
// }
// }
impl Solution {
- pub fn get_decimal_value(head: Option>) -> i32 {
+ pub fn get_decimal_value(mut head: Option>) -> i32 {
let mut ans = 0;
- let mut cur = &head;
- while let Some(node) = cur {
+ while let Some(node) = head {
ans = (ans << 1) | node.val;
- cur = &node.next;
+ head = node.next;
}
ans
}
@@ -223,6 +228,31 @@ var getDecimalValue = function (head) {
};
```
+#### C#
+
+```cs
+/**
+ * Definition for singly-linked list.
+ * public class ListNode {
+ * public int val;
+ * public ListNode next;
+ * public ListNode(int val=0, ListNode next=null) {
+ * this.val = val;
+ * this.next = next;
+ * }
+ * }
+ */
+public class Solution {
+ public int GetDecimalValue(ListNode head) {
+ int ans = 0;
+ for (; head != null; head = head.next) {
+ ans = ans << 1 | head.val;
+ }
+ return ans;
+ }
+}
+```
+
#### PHP
```php
@@ -243,13 +273,12 @@ class Solution {
* @return Integer
*/
function getDecimalValue($head) {
- $rs = [];
- while ($head != null) {
- array_push($rs, $head->val);
+ $ans = 0;
+ while ($head !== null) {
+ $ans = ($ans << 1) | $head->val;
$head = $head->next;
}
- $rsStr = implode($rs);
- return bindec($rsStr);
+ return $ans;
}
}
```
diff --git a/solution/1200-1299/1290.Convert Binary Number in a Linked List to Integer/Solution.cs b/solution/1200-1299/1290.Convert Binary Number in a Linked List to Integer/Solution.cs
new file mode 100644
index 0000000000000..bbfcf9dbff062
--- /dev/null
+++ b/solution/1200-1299/1290.Convert Binary Number in a Linked List to Integer/Solution.cs
@@ -0,0 +1,20 @@
+/**
+ * Definition for singly-linked list.
+ * public class ListNode {
+ * public int val;
+ * public ListNode next;
+ * public ListNode(int val=0, ListNode next=null) {
+ * this.val = val;
+ * this.next = next;
+ * }
+ * }
+ */
+public class Solution {
+ public int GetDecimalValue(ListNode head) {
+ int ans = 0;
+ for (; head != null; head = head.next) {
+ ans = ans << 1 | head.val;
+ }
+ return ans;
+ }
+}
\ No newline at end of file
diff --git a/solution/1200-1299/1290.Convert Binary Number in a Linked List to Integer/Solution.php b/solution/1200-1299/1290.Convert Binary Number in a Linked List to Integer/Solution.php
index 7ddaf720fe6ae..514bc47573ca4 100644
--- a/solution/1200-1299/1290.Convert Binary Number in a Linked List to Integer/Solution.php
+++ b/solution/1200-1299/1290.Convert Binary Number in a Linked List to Integer/Solution.php
@@ -15,12 +15,11 @@ class Solution {
* @return Integer
*/
function getDecimalValue($head) {
- $rs = [];
- while ($head != null) {
- array_push($rs, $head->val);
+ $ans = 0;
+ while ($head !== null) {
+ $ans = ($ans << 1) | $head->val;
$head = $head->next;
}
- $rsStr = implode($rs);
- return bindec($rsStr);
+ return $ans;
}
}
\ No newline at end of file
diff --git a/solution/1200-1299/1290.Convert Binary Number in a Linked List to Integer/Solution.rs b/solution/1200-1299/1290.Convert Binary Number in a Linked List to Integer/Solution.rs
index 7c122a66fc0df..b3f205ea5f95c 100644
--- a/solution/1200-1299/1290.Convert Binary Number in a Linked List to Integer/Solution.rs
+++ b/solution/1200-1299/1290.Convert Binary Number in a Linked List to Integer/Solution.rs
@@ -15,12 +15,11 @@
// }
// }
impl Solution {
- pub fn get_decimal_value(head: Option>) -> i32 {
+ pub fn get_decimal_value(mut head: Option>) -> i32 {
let mut ans = 0;
- let mut cur = &head;
- while let Some(node) = cur {
+ while let Some(node) = head {
ans = (ans << 1) | node.val;
- cur = &node.next;
+ head = node.next;
}
ans
}
diff --git a/solution/1200-1299/1295.Find Numbers with Even Number of Digits/README.md b/solution/1200-1299/1295.Find Numbers with Even Number of Digits/README.md
index 6a05d1729477a..f8c826b083334 100644
--- a/solution/1200-1299/1295.Find Numbers with Even Number of Digits/README.md
+++ b/solution/1200-1299/1295.Find Numbers with Even Number of Digits/README.md
@@ -19,7 +19,7 @@ tags:
-给你一个整数数组 nums
,请你返回其中位数为 偶数 的数字的个数。
+给你一个整数数组 nums
,请你返回其中包含 偶数 个数位的数字的个数。
@@ -131,6 +131,16 @@ function findNumbers(nums: number[]): number {
}
```
+#### Rust
+
+```rust
+impl Solution {
+ pub fn find_numbers(nums: Vec) -> i32 {
+ nums.iter().filter(|&x| x.to_string().len() % 2 == 0).count() as i32
+ }
+}
+```
+
#### JavaScript
```js
@@ -143,6 +153,16 @@ var findNumbers = function (nums) {
};
```
+#### C#
+
+```cs
+public class Solution {
+ public int FindNumbers(int[] nums) {
+ return nums.Count(x => x.ToString().Length % 2 == 0);
+ }
+}
+```
+
diff --git a/solution/1200-1299/1295.Find Numbers with Even Number of Digits/README_EN.md b/solution/1200-1299/1295.Find Numbers with Even Number of Digits/README_EN.md
index 85b2b1a18b99c..9c6351d5539df 100644
--- a/solution/1200-1299/1295.Find Numbers with Even Number of Digits/README_EN.md
+++ b/solution/1200-1299/1295.Find Numbers with Even Number of Digits/README_EN.md
@@ -129,6 +129,16 @@ function findNumbers(nums: number[]): number {
}
```
+#### Rust
+
+```rust
+impl Solution {
+ pub fn find_numbers(nums: Vec) -> i32 {
+ nums.iter().filter(|&x| x.to_string().len() % 2 == 0).count() as i32
+ }
+}
+```
+
#### JavaScript
```js
@@ -141,6 +151,16 @@ var findNumbers = function (nums) {
};
```
+#### C#
+
+```cs
+public class Solution {
+ public int FindNumbers(int[] nums) {
+ return nums.Count(x => x.ToString().Length % 2 == 0);
+ }
+}
+```
+
diff --git a/solution/1200-1299/1295.Find Numbers with Even Number of Digits/Solution.rs b/solution/1200-1299/1295.Find Numbers with Even Number of Digits/Solution.rs
new file mode 100644
index 0000000000000..26d91b28a550d
--- /dev/null
+++ b/solution/1200-1299/1295.Find Numbers with Even Number of Digits/Solution.rs
@@ -0,0 +1,7 @@
+impl Solution {
+ pub fn find_numbers(nums: Vec) -> i32 {
+ nums.iter()
+ .filter(|&x| x.to_string().len() % 2 == 0)
+ .count() as i32
+ }
+}
diff --git a/solution/1200-1299/1295.Find Numbers with Even Number of Digits/Soluton.cs b/solution/1200-1299/1295.Find Numbers with Even Number of Digits/Soluton.cs
new file mode 100644
index 0000000000000..4a98e37e739fe
--- /dev/null
+++ b/solution/1200-1299/1295.Find Numbers with Even Number of Digits/Soluton.cs
@@ -0,0 +1,5 @@
+public class Solution {
+ public int FindNumbers(int[] nums) {
+ return nums.Count(x => x.ToString().Length % 2 == 0);
+ }
+}
\ No newline at end of file
diff --git a/solution/1200-1299/1298.Maximum Candies You Can Get from Boxes/README.md b/solution/1200-1299/1298.Maximum Candies You Can Get from Boxes/README.md
index d974408e38dbb..d3430a8b06093 100644
--- a/solution/1200-1299/1298.Maximum Candies You Can Get from Boxes/README.md
+++ b/solution/1200-1299/1298.Maximum Candies You Can Get from Boxes/README.md
@@ -29,7 +29,7 @@ tags:
内含的盒子 containedBoxes[i]
:整数,表示放在 box[i]
里的盒子所对应的下标。
-给你一个 initialBoxes
数组,表示你现在得到的盒子,你可以获得里面的糖果,也可以用盒子里的钥匙打开新的盒子,还可以继续探索从这个盒子里找到的其他盒子。
+给你一个整数数组 initialBoxes
,包含你最初拥有的盒子。你可以拿走每个 已打开盒子 里的所有糖果,并且可以使用其中的钥匙去开启新的盒子,并且可以使用在其中发现的其他盒子。
请你按照上述规则,返回可以获得糖果的 最大数目 。
@@ -37,7 +37,8 @@ tags:
示例 1:
-输入:status = [1,0,1,0], candies = [7,5,4,100], keys = [[],[],[1],[]], containedBoxes = [[1,2],[3],[],[]], initialBoxes = [0]
+
+输入:status = [1,0,1,0], candies = [7,5,4,100], keys = [[],[],[1],[]], containedBoxes = [[1,2],[3],[],[]], initialBoxes = [0]
输出:16
解释:
一开始你有盒子 0 。你将获得它里面的 7 个糖果和盒子 1 和 2。
@@ -48,7 +49,8 @@ tags:
示例 2:
-输入:status = [1,0,0,0,0,0], candies = [1,1,1,1,1,1], keys = [[1,2,3,4,5],[],[],[],[],[]], containedBoxes = [[1,2,3,4,5],[],[],[],[],[]], initialBoxes = [0]
+
+输入:status = [1,0,0,0,0,0], candies = [1,1,1,1,1,1], keys = [[1,2,3,4,5],[],[],[],[],[]], containedBoxes = [[1,2,3,4,5],[],[],[],[],[]], initialBoxes = [0]
输出:6
解释:
你一开始拥有盒子 0 。打开它你可以找到盒子 1,2,3,4,5 和它们对应的钥匙。
@@ -57,19 +59,22 @@ tags:
示例 3:
-输入:status = [1,1,1], candies = [100,1,100], keys = [[],[0,2],[]], containedBoxes = [[],[],[]], initialBoxes = [1]
+
+输入:status = [1,1,1], candies = [100,1,100], keys = [[],[0,2],[]], containedBoxes = [[],[],[]], initialBoxes = [1]
输出:1
示例 4:
-输入:status = [1], candies = [100], keys = [[]], containedBoxes = [[]], initialBoxes = []
+
+输入:status = [1], candies = [100], keys = [[]], containedBoxes = [[]], initialBoxes = []
输出:0
示例 5:
-输入:status = [1,1,1], candies = [2,3,2], keys = [[],[],[]], containedBoxes = [[],[],[]], initialBoxes = [2,1,0]
+
+输入:status = [1,1,1], candies = [2,3,2], keys = [[],[],[]], containedBoxes = [[],[],[]], initialBoxes = [2,1,0]
输出:7
@@ -99,7 +104,24 @@ tags:
-### 方法一:BFS
+### 方法一:BFS + 哈希集合
+
+题目给定一批盒子,每个盒子可能有状态(开/关)、糖果、钥匙、以及其他盒子。我们的目标是通过初始给定的一些盒子,尽可能多地打开更多盒子,并收集其中的糖果。可以通过获得钥匙来解锁新盒子,通过盒子中嵌套的盒子来获取更多资源。
+
+我们采用 BFS 的方式模拟整个探索过程。
+
+我们用一个队列 $q$ 表示当前可以访问的、**已经开启** 的盒子;用两个集合 $\textit{has}$ 和 $\textit{took}$ 分别记录**我们拥有的所有盒子**和**已经处理过的盒子**,防止重复。
+
+初始时,将所有 $\textit{initialBoxes}$ 添加到 $\textit{has}$ 中,如果初始盒子状态为开启,立即加入队列 $\textit{q}$ 并累计糖果;
+
+然后进行 BFS,依次从 $\textit{q}$ 中取出盒子:
+
+- 获取盒子中的钥匙 $\textit{keys[box]}$,将能解锁的盒子加入队列;
+- 收集盒子中包含的其他盒子 $\textit{containedBoxes[box]}$,如果状态是开启的且未处理过,则立即处理;
+
+每个盒子最多处理一次,糖果累计一次,最终返回总糖果数 $\textit{ans}$。
+
+时间复杂度 $O(n)$,空间复杂度 $O(n)$,其中 $n$ 是盒子的总数。
@@ -115,25 +137,31 @@ class Solution:
containedBoxes: List[List[int]],
initialBoxes: List[int],
) -> int:
- q = deque([i for i in initialBoxes if status[i] == 1])
- ans = sum(candies[i] for i in initialBoxes if status[i] == 1)
- has = set(initialBoxes)
- took = {i for i in initialBoxes if status[i] == 1}
-
+ q = deque()
+ has, took = set(initialBoxes), set()
+ ans = 0
+
+ for box in initialBoxes:
+ if status[box]:
+ q.append(box)
+ took.add(box)
+ ans += candies[box]
while q:
- i = q.popleft()
- for k in keys[i]:
- status[k] = 1
- if k in has and k not in took:
- ans += candies[k]
- took.add(k)
- q.append(k)
- for j in containedBoxes[i]:
- has.add(j)
- if status[j] and j not in took:
- ans += candies[j]
- took.add(j)
- q.append(j)
+ box = q.popleft()
+ for k in keys[box]:
+ if not status[k]:
+ status[k] = 1
+ if k in has and k not in took:
+ q.append(k)
+ took.add(k)
+ ans += candies[k]
+
+ for b in containedBoxes[box]:
+ has.add(b)
+ if status[b] and b not in took:
+ q.append(b)
+ took.add(b)
+ ans += candies[b]
return ans
```
@@ -143,35 +171,36 @@ class Solution:
class Solution {
public int maxCandies(
int[] status, int[] candies, int[][] keys, int[][] containedBoxes, int[] initialBoxes) {
- int ans = 0;
- int n = status.length;
- boolean[] has = new boolean[n];
- boolean[] took = new boolean[n];
Deque q = new ArrayDeque<>();
- for (int i : initialBoxes) {
- has[i] = true;
- if (status[i] == 1) {
- ans += candies[i];
- took[i] = true;
- q.offer(i);
+ Set has = new HashSet<>();
+ Set took = new HashSet<>();
+ int ans = 0;
+ for (int box : initialBoxes) {
+ has.add(box);
+ if (status[box] == 1) {
+ q.offer(box);
+ took.add(box);
+ ans += candies[box];
}
}
while (!q.isEmpty()) {
- int i = q.poll();
- for (int k : keys[i]) {
- status[k] = 1;
- if (has[k] && !took[k]) {
- ans += candies[k];
- took[k] = true;
- q.offer(k);
+ int box = q.poll();
+ for (int k : keys[box]) {
+ if (status[k] == 0) {
+ status[k] = 1;
+ if (has.contains(k) && !took.contains(k)) {
+ q.offer(k);
+ took.add(k);
+ ans += candies[k];
+ }
}
}
- for (int j : containedBoxes[i]) {
- has[j] = true;
- if (status[j] == 1 && !took[j]) {
- ans += candies[j];
- took[j] = true;
- q.offer(j);
+ for (int b : containedBoxes[box]) {
+ has.add(b);
+ if (status[b] == 1 && !took.contains(b)) {
+ q.offer(b);
+ took.add(b);
+ ans += candies[b];
}
}
}
@@ -185,40 +214,50 @@ class Solution {
```cpp
class Solution {
public:
- int maxCandies(vector& status, vector& candies, vector>& keys, vector>& containedBoxes, vector& initialBoxes) {
- int ans = 0;
- int n = status.size();
- vector has(n);
- vector took(n);
+ int maxCandies(
+ vector& status,
+ vector& candies,
+ vector>& keys,
+ vector>& containedBoxes,
+ vector& initialBoxes) {
queue q;
- for (int& i : initialBoxes) {
- has[i] = true;
- if (status[i]) {
- ans += candies[i];
- took[i] = true;
- q.push(i);
+ unordered_set has, took;
+ int ans = 0;
+
+ for (int box : initialBoxes) {
+ has.insert(box);
+ if (status[box]) {
+ q.push(box);
+ took.insert(box);
+ ans += candies[box];
}
}
+
while (!q.empty()) {
- int i = q.front();
+ int box = q.front();
q.pop();
- for (int k : keys[i]) {
- status[k] = 1;
- if (has[k] && !took[k]) {
- ans += candies[k];
- took[k] = true;
- q.push(k);
+
+ for (int k : keys[box]) {
+ if (!status[k]) {
+ status[k] = 1;
+ if (has.count(k) && !took.count(k)) {
+ q.push(k);
+ took.insert(k);
+ ans += candies[k];
+ }
}
}
- for (int j : containedBoxes[i]) {
- has[j] = true;
- if (status[j] && !took[j]) {
- ans += candies[j];
- took[j] = true;
- q.push(j);
+
+ for (int b : containedBoxes[box]) {
+ has.insert(b);
+ if (status[b] && !took.count(b)) {
+ q.push(b);
+ took.insert(b);
+ ans += candies[b];
}
}
}
+
return ans;
}
};
@@ -227,41 +266,147 @@ public:
#### Go
```go
-func maxCandies(status []int, candies []int, keys [][]int, containedBoxes [][]int, initialBoxes []int) int {
- ans := 0
- n := len(status)
- has := make([]bool, n)
- took := make([]bool, n)
- var q []int
- for _, i := range initialBoxes {
- has[i] = true
- if status[i] == 1 {
- ans += candies[i]
- took[i] = true
- q = append(q, i)
+func maxCandies(status []int, candies []int, keys [][]int, containedBoxes [][]int, initialBoxes []int) (ans int) {
+ q := []int{}
+ has := make(map[int]bool)
+ took := make(map[int]bool)
+ for _, box := range initialBoxes {
+ has[box] = true
+ if status[box] == 1 {
+ q = append(q, box)
+ took[box] = true
+ ans += candies[box]
}
}
for len(q) > 0 {
- i := q[0]
+ box := q[0]
q = q[1:]
- for _, k := range keys[i] {
- status[k] = 1
- if has[k] && !took[k] {
- ans += candies[k]
- took[k] = true
- q = append(q, k)
+ for _, k := range keys[box] {
+ if status[k] == 0 {
+ status[k] = 1
+ if has[k] && !took[k] {
+ q = append(q, k)
+ took[k] = true
+ ans += candies[k]
+ }
}
}
- for _, j := range containedBoxes[i] {
- has[j] = true
- if status[j] == 1 && !took[j] {
- ans += candies[j]
- took[j] = true
- q = append(q, j)
+ for _, b := range containedBoxes[box] {
+ has[b] = true
+ if status[b] == 1 && !took[b] {
+ q = append(q, b)
+ took[b] = true
+ ans += candies[b]
}
}
}
- return ans
+ return
+}
+```
+
+#### TypeScript
+
+```ts
+function maxCandies(
+ status: number[],
+ candies: number[],
+ keys: number[][],
+ containedBoxes: number[][],
+ initialBoxes: number[],
+): number {
+ const q: number[] = [];
+ const has: Set = new Set();
+ const took: Set = new Set();
+ let ans = 0;
+
+ for (const box of initialBoxes) {
+ has.add(box);
+ if (status[box] === 1) {
+ q.push(box);
+ took.add(box);
+ ans += candies[box];
+ }
+ }
+
+ while (q.length > 0) {
+ const box = q.pop()!;
+
+ for (const k of keys[box]) {
+ if (status[k] === 0) {
+ status[k] = 1;
+ if (has.has(k) && !took.has(k)) {
+ q.push(k);
+ took.add(k);
+ ans += candies[k];
+ }
+ }
+ }
+
+ for (const b of containedBoxes[box]) {
+ has.add(b);
+ if (status[b] === 1 && !took.has(b)) {
+ q.push(b);
+ took.add(b);
+ ans += candies[b];
+ }
+ }
+ }
+
+ return ans;
+}
+```
+
+#### Rust
+
+```rust
+use std::collections::{HashSet, VecDeque};
+
+impl Solution {
+ pub fn max_candies(
+ mut status: Vec,
+ candies: Vec,
+ keys: Vec>,
+ contained_boxes: Vec>,
+ initial_boxes: Vec,
+ ) -> i32 {
+ let mut q: VecDeque = VecDeque::new();
+ let mut has: HashSet = HashSet::new();
+ let mut took: HashSet = HashSet::new();
+ let mut ans = 0;
+
+ for &box_ in &initial_boxes {
+ has.insert(box_);
+ if status[box_ as usize] == 1 {
+ q.push_back(box_);
+ took.insert(box_);
+ ans += candies[box_ as usize];
+ }
+ }
+
+ while let Some(box_) = q.pop_front() {
+ for &k in &keys[box_ as usize] {
+ if status[k as usize] == 0 {
+ status[k as usize] = 1;
+ if has.contains(&k) && !took.contains(&k) {
+ q.push_back(k);
+ took.insert(k);
+ ans += candies[k as usize];
+ }
+ }
+ }
+
+ for &b in &contained_boxes[box_ as usize] {
+ has.insert(b);
+ if status[b as usize] == 1 && !took.contains(&b) {
+ q.push_back(b);
+ took.insert(b);
+ ans += candies[b as usize];
+ }
+ }
+ }
+
+ ans
+ }
}
```
diff --git a/solution/1200-1299/1298.Maximum Candies You Can Get from Boxes/README_EN.md b/solution/1200-1299/1298.Maximum Candies You Can Get from Boxes/README_EN.md
index 206d86924e214..3e1c094f6f83d 100644
--- a/solution/1200-1299/1298.Maximum Candies You Can Get from Boxes/README_EN.md
+++ b/solution/1200-1299/1298.Maximum Candies You Can Get from Boxes/README_EN.md
@@ -79,7 +79,24 @@ The total number of candies will be 6.
-### Solution 1
+### Solution 1: BFS + Hash Set
+
+The problem gives a set of boxes, each of which may have a state (open/closed), candies, keys, and other boxes inside. Our goal is to use the initially given boxes to open as many more boxes as possible and collect the candies inside. We can unlock new boxes by obtaining keys, and get more resources through boxes nested inside other boxes.
+
+We use BFS to simulate the entire exploration process.
+
+We use a queue $q$ to represent the currently accessible and **already opened** boxes; two sets, $\textit{has}$ and $\textit{took}$, are used to record **all boxes we own** and **boxes we have already processed**, to avoid duplicates.
+
+Initially, add all $\textit{initialBoxes}$ to $\textit{has}$. If an initial box is open, immediately add it to the queue $\textit{q}$ and accumulate its candies.
+
+Then perform BFS, taking boxes out of $\textit{q}$ one by one:
+
+- Obtain the keys in the box $\textit{keys[box]}$ and add any boxes that can be unlocked to the queue;
+- Collect other boxes contained in the box $\textit{containedBoxes[box]}$. If a contained box is open and has not been processed, process it immediately;
+
+Each box is processed at most once, and candies are accumulated once. Finally, return the total number of candies $\textit{ans}$.
+
+The time complexity is $O(n)$, and the space complexity is $O(n)$, where $n$ is the total number of boxes.
@@ -95,25 +112,31 @@ class Solution:
containedBoxes: List[List[int]],
initialBoxes: List[int],
) -> int:
- q = deque([i for i in initialBoxes if status[i] == 1])
- ans = sum(candies[i] for i in initialBoxes if status[i] == 1)
- has = set(initialBoxes)
- took = {i for i in initialBoxes if status[i] == 1}
-
+ q = deque()
+ has, took = set(initialBoxes), set()
+ ans = 0
+
+ for box in initialBoxes:
+ if status[box]:
+ q.append(box)
+ took.add(box)
+ ans += candies[box]
while q:
- i = q.popleft()
- for k in keys[i]:
- status[k] = 1
- if k in has and k not in took:
- ans += candies[k]
- took.add(k)
- q.append(k)
- for j in containedBoxes[i]:
- has.add(j)
- if status[j] and j not in took:
- ans += candies[j]
- took.add(j)
- q.append(j)
+ box = q.popleft()
+ for k in keys[box]:
+ if not status[k]:
+ status[k] = 1
+ if k in has and k not in took:
+ q.append(k)
+ took.add(k)
+ ans += candies[k]
+
+ for b in containedBoxes[box]:
+ has.add(b)
+ if status[b] and b not in took:
+ q.append(b)
+ took.add(b)
+ ans += candies[b]
return ans
```
@@ -123,35 +146,36 @@ class Solution:
class Solution {
public int maxCandies(
int[] status, int[] candies, int[][] keys, int[][] containedBoxes, int[] initialBoxes) {
- int ans = 0;
- int n = status.length;
- boolean[] has = new boolean[n];
- boolean[] took = new boolean[n];
Deque q = new ArrayDeque<>();
- for (int i : initialBoxes) {
- has[i] = true;
- if (status[i] == 1) {
- ans += candies[i];
- took[i] = true;
- q.offer(i);
+ Set has = new HashSet<>();
+ Set took = new HashSet<>();
+ int ans = 0;
+ for (int box : initialBoxes) {
+ has.add(box);
+ if (status[box] == 1) {
+ q.offer(box);
+ took.add(box);
+ ans += candies[box];
}
}
while (!q.isEmpty()) {
- int i = q.poll();
- for (int k : keys[i]) {
- status[k] = 1;
- if (has[k] && !took[k]) {
- ans += candies[k];
- took[k] = true;
- q.offer(k);
+ int box = q.poll();
+ for (int k : keys[box]) {
+ if (status[k] == 0) {
+ status[k] = 1;
+ if (has.contains(k) && !took.contains(k)) {
+ q.offer(k);
+ took.add(k);
+ ans += candies[k];
+ }
}
}
- for (int j : containedBoxes[i]) {
- has[j] = true;
- if (status[j] == 1 && !took[j]) {
- ans += candies[j];
- took[j] = true;
- q.offer(j);
+ for (int b : containedBoxes[box]) {
+ has.add(b);
+ if (status[b] == 1 && !took.contains(b)) {
+ q.offer(b);
+ took.add(b);
+ ans += candies[b];
}
}
}
@@ -165,40 +189,50 @@ class Solution {
```cpp
class Solution {
public:
- int maxCandies(vector& status, vector& candies, vector>& keys, vector>& containedBoxes, vector& initialBoxes) {
- int ans = 0;
- int n = status.size();
- vector has(n);
- vector took(n);
+ int maxCandies(
+ vector& status,
+ vector& candies,
+ vector>& keys,
+ vector>& containedBoxes,
+ vector& initialBoxes) {
queue q;
- for (int& i : initialBoxes) {
- has[i] = true;
- if (status[i]) {
- ans += candies[i];
- took[i] = true;
- q.push(i);
+ unordered_set has, took;
+ int ans = 0;
+
+ for (int box : initialBoxes) {
+ has.insert(box);
+ if (status[box]) {
+ q.push(box);
+ took.insert(box);
+ ans += candies[box];
}
}
+
while (!q.empty()) {
- int i = q.front();
+ int box = q.front();
q.pop();
- for (int k : keys[i]) {
- status[k] = 1;
- if (has[k] && !took[k]) {
- ans += candies[k];
- took[k] = true;
- q.push(k);
+
+ for (int k : keys[box]) {
+ if (!status[k]) {
+ status[k] = 1;
+ if (has.count(k) && !took.count(k)) {
+ q.push(k);
+ took.insert(k);
+ ans += candies[k];
+ }
}
}
- for (int j : containedBoxes[i]) {
- has[j] = true;
- if (status[j] && !took[j]) {
- ans += candies[j];
- took[j] = true;
- q.push(j);
+
+ for (int b : containedBoxes[box]) {
+ has.insert(b);
+ if (status[b] && !took.count(b)) {
+ q.push(b);
+ took.insert(b);
+ ans += candies[b];
}
}
}
+
return ans;
}
};
@@ -207,41 +241,147 @@ public:
#### Go
```go
-func maxCandies(status []int, candies []int, keys [][]int, containedBoxes [][]int, initialBoxes []int) int {
- ans := 0
- n := len(status)
- has := make([]bool, n)
- took := make([]bool, n)
- var q []int
- for _, i := range initialBoxes {
- has[i] = true
- if status[i] == 1 {
- ans += candies[i]
- took[i] = true
- q = append(q, i)
+func maxCandies(status []int, candies []int, keys [][]int, containedBoxes [][]int, initialBoxes []int) (ans int) {
+ q := []int{}
+ has := make(map[int]bool)
+ took := make(map[int]bool)
+ for _, box := range initialBoxes {
+ has[box] = true
+ if status[box] == 1 {
+ q = append(q, box)
+ took[box] = true
+ ans += candies[box]
}
}
for len(q) > 0 {
- i := q[0]
+ box := q[0]
q = q[1:]
- for _, k := range keys[i] {
- status[k] = 1
- if has[k] && !took[k] {
- ans += candies[k]
- took[k] = true
- q = append(q, k)
+ for _, k := range keys[box] {
+ if status[k] == 0 {
+ status[k] = 1
+ if has[k] && !took[k] {
+ q = append(q, k)
+ took[k] = true
+ ans += candies[k]
+ }
}
}
- for _, j := range containedBoxes[i] {
- has[j] = true
- if status[j] == 1 && !took[j] {
- ans += candies[j]
- took[j] = true
- q = append(q, j)
+ for _, b := range containedBoxes[box] {
+ has[b] = true
+ if status[b] == 1 && !took[b] {
+ q = append(q, b)
+ took[b] = true
+ ans += candies[b]
}
}
}
- return ans
+ return
+}
+```
+
+#### TypeScript
+
+```ts
+function maxCandies(
+ status: number[],
+ candies: number[],
+ keys: number[][],
+ containedBoxes: number[][],
+ initialBoxes: number[],
+): number {
+ const q: number[] = [];
+ const has: Set = new Set();
+ const took: Set = new Set();
+ let ans = 0;
+
+ for (const box of initialBoxes) {
+ has.add(box);
+ if (status[box] === 1) {
+ q.push(box);
+ took.add(box);
+ ans += candies[box];
+ }
+ }
+
+ while (q.length > 0) {
+ const box = q.pop()!;
+
+ for (const k of keys[box]) {
+ if (status[k] === 0) {
+ status[k] = 1;
+ if (has.has(k) && !took.has(k)) {
+ q.push(k);
+ took.add(k);
+ ans += candies[k];
+ }
+ }
+ }
+
+ for (const b of containedBoxes[box]) {
+ has.add(b);
+ if (status[b] === 1 && !took.has(b)) {
+ q.push(b);
+ took.add(b);
+ ans += candies[b];
+ }
+ }
+ }
+
+ return ans;
+}
+```
+
+#### Rust
+
+```rust
+use std::collections::{HashSet, VecDeque};
+
+impl Solution {
+ pub fn max_candies(
+ mut status: Vec,
+ candies: Vec,
+ keys: Vec>,
+ contained_boxes: Vec>,
+ initial_boxes: Vec,
+ ) -> i32 {
+ let mut q: VecDeque = VecDeque::new();
+ let mut has: HashSet = HashSet::new();
+ let mut took: HashSet = HashSet::new();
+ let mut ans = 0;
+
+ for &box_ in &initial_boxes {
+ has.insert(box_);
+ if status[box_ as usize] == 1 {
+ q.push_back(box_);
+ took.insert(box_);
+ ans += candies[box_ as usize];
+ }
+ }
+
+ while let Some(box_) = q.pop_front() {
+ for &k in &keys[box_ as usize] {
+ if status[k as usize] == 0 {
+ status[k as usize] = 1;
+ if has.contains(&k) && !took.contains(&k) {
+ q.push_back(k);
+ took.insert(k);
+ ans += candies[k as usize];
+ }
+ }
+ }
+
+ for &b in &contained_boxes[box_ as usize] {
+ has.insert(b);
+ if status[b as usize] == 1 && !took.contains(&b) {
+ q.push_back(b);
+ took.insert(b);
+ ans += candies[b as usize];
+ }
+ }
+ }
+
+ ans
+ }
}
```
diff --git a/solution/1200-1299/1298.Maximum Candies You Can Get from Boxes/Solution.cpp b/solution/1200-1299/1298.Maximum Candies You Can Get from Boxes/Solution.cpp
index 7b85217a5a1f3..fffc87bc0c3df 100644
--- a/solution/1200-1299/1298.Maximum Candies You Can Get from Boxes/Solution.cpp
+++ b/solution/1200-1299/1298.Maximum Candies You Can Get from Boxes/Solution.cpp
@@ -1,39 +1,49 @@
class Solution {
public:
- int maxCandies(vector& status, vector& candies, vector>& keys, vector>& containedBoxes, vector& initialBoxes) {
- int ans = 0;
- int n = status.size();
- vector has(n);
- vector took(n);
+ int maxCandies(
+ vector& status,
+ vector& candies,
+ vector>& keys,
+ vector>& containedBoxes,
+ vector& initialBoxes) {
queue q;
- for (int& i : initialBoxes) {
- has[i] = true;
- if (status[i]) {
- ans += candies[i];
- took[i] = true;
- q.push(i);
+ unordered_set has, took;
+ int ans = 0;
+
+ for (int box : initialBoxes) {
+ has.insert(box);
+ if (status[box]) {
+ q.push(box);
+ took.insert(box);
+ ans += candies[box];
}
}
+
while (!q.empty()) {
- int i = q.front();
+ int box = q.front();
q.pop();
- for (int k : keys[i]) {
- status[k] = 1;
- if (has[k] && !took[k]) {
- ans += candies[k];
- took[k] = true;
- q.push(k);
+
+ for (int k : keys[box]) {
+ if (!status[k]) {
+ status[k] = 1;
+ if (has.count(k) && !took.count(k)) {
+ q.push(k);
+ took.insert(k);
+ ans += candies[k];
+ }
}
}
- for (int j : containedBoxes[i]) {
- has[j] = true;
- if (status[j] && !took[j]) {
- ans += candies[j];
- took[j] = true;
- q.push(j);
+
+ for (int b : containedBoxes[box]) {
+ has.insert(b);
+ if (status[b] && !took.count(b)) {
+ q.push(b);
+ took.insert(b);
+ ans += candies[b];
}
}
}
+
return ans;
}
-};
\ No newline at end of file
+};
diff --git a/solution/1200-1299/1298.Maximum Candies You Can Get from Boxes/Solution.go b/solution/1200-1299/1298.Maximum Candies You Can Get from Boxes/Solution.go
index 4ff69d070109e..610853ade8f02 100644
--- a/solution/1200-1299/1298.Maximum Candies You Can Get from Boxes/Solution.go
+++ b/solution/1200-1299/1298.Maximum Candies You Can Get from Boxes/Solution.go
@@ -1,36 +1,36 @@
-func maxCandies(status []int, candies []int, keys [][]int, containedBoxes [][]int, initialBoxes []int) int {
- ans := 0
- n := len(status)
- has := make([]bool, n)
- took := make([]bool, n)
- var q []int
- for _, i := range initialBoxes {
- has[i] = true
- if status[i] == 1 {
- ans += candies[i]
- took[i] = true
- q = append(q, i)
+func maxCandies(status []int, candies []int, keys [][]int, containedBoxes [][]int, initialBoxes []int) (ans int) {
+ q := []int{}
+ has := make(map[int]bool)
+ took := make(map[int]bool)
+ for _, box := range initialBoxes {
+ has[box] = true
+ if status[box] == 1 {
+ q = append(q, box)
+ took[box] = true
+ ans += candies[box]
}
}
for len(q) > 0 {
- i := q[0]
+ box := q[0]
q = q[1:]
- for _, k := range keys[i] {
- status[k] = 1
- if has[k] && !took[k] {
- ans += candies[k]
- took[k] = true
- q = append(q, k)
+ for _, k := range keys[box] {
+ if status[k] == 0 {
+ status[k] = 1
+ if has[k] && !took[k] {
+ q = append(q, k)
+ took[k] = true
+ ans += candies[k]
+ }
}
}
- for _, j := range containedBoxes[i] {
- has[j] = true
- if status[j] == 1 && !took[j] {
- ans += candies[j]
- took[j] = true
- q = append(q, j)
+ for _, b := range containedBoxes[box] {
+ has[b] = true
+ if status[b] == 1 && !took[b] {
+ q = append(q, b)
+ took[b] = true
+ ans += candies[b]
}
}
}
- return ans
-}
\ No newline at end of file
+ return
+}
diff --git a/solution/1200-1299/1298.Maximum Candies You Can Get from Boxes/Solution.java b/solution/1200-1299/1298.Maximum Candies You Can Get from Boxes/Solution.java
index 3d9e243bfdfa3..d473b7305010c 100644
--- a/solution/1200-1299/1298.Maximum Candies You Can Get from Boxes/Solution.java
+++ b/solution/1200-1299/1298.Maximum Candies You Can Get from Boxes/Solution.java
@@ -1,38 +1,39 @@
class Solution {
public int maxCandies(
int[] status, int[] candies, int[][] keys, int[][] containedBoxes, int[] initialBoxes) {
- int ans = 0;
- int n = status.length;
- boolean[] has = new boolean[n];
- boolean[] took = new boolean[n];
Deque q = new ArrayDeque<>();
- for (int i : initialBoxes) {
- has[i] = true;
- if (status[i] == 1) {
- ans += candies[i];
- took[i] = true;
- q.offer(i);
+ Set has = new HashSet<>();
+ Set took = new HashSet<>();
+ int ans = 0;
+ for (int box : initialBoxes) {
+ has.add(box);
+ if (status[box] == 1) {
+ q.offer(box);
+ took.add(box);
+ ans += candies[box];
}
}
while (!q.isEmpty()) {
- int i = q.poll();
- for (int k : keys[i]) {
- status[k] = 1;
- if (has[k] && !took[k]) {
- ans += candies[k];
- took[k] = true;
- q.offer(k);
+ int box = q.poll();
+ for (int k : keys[box]) {
+ if (status[k] == 0) {
+ status[k] = 1;
+ if (has.contains(k) && !took.contains(k)) {
+ q.offer(k);
+ took.add(k);
+ ans += candies[k];
+ }
}
}
- for (int j : containedBoxes[i]) {
- has[j] = true;
- if (status[j] == 1 && !took[j]) {
- ans += candies[j];
- took[j] = true;
- q.offer(j);
+ for (int b : containedBoxes[box]) {
+ has.add(b);
+ if (status[b] == 1 && !took.contains(b)) {
+ q.offer(b);
+ took.add(b);
+ ans += candies[b];
}
}
}
return ans;
}
-}
\ No newline at end of file
+}
diff --git a/solution/1200-1299/1298.Maximum Candies You Can Get from Boxes/Solution.py b/solution/1200-1299/1298.Maximum Candies You Can Get from Boxes/Solution.py
index fe996159a7a50..2aed0b52ec7ef 100644
--- a/solution/1200-1299/1298.Maximum Candies You Can Get from Boxes/Solution.py
+++ b/solution/1200-1299/1298.Maximum Candies You Can Get from Boxes/Solution.py
@@ -7,23 +7,29 @@ def maxCandies(
containedBoxes: List[List[int]],
initialBoxes: List[int],
) -> int:
- q = deque([i for i in initialBoxes if status[i] == 1])
- ans = sum(candies[i] for i in initialBoxes if status[i] == 1)
- has = set(initialBoxes)
- took = {i for i in initialBoxes if status[i] == 1}
+ q = deque()
+ has, took = set(initialBoxes), set()
+ ans = 0
+ for box in initialBoxes:
+ if status[box]:
+ q.append(box)
+ took.add(box)
+ ans += candies[box]
while q:
- i = q.popleft()
- for k in keys[i]:
- status[k] = 1
- if k in has and k not in took:
- ans += candies[k]
- took.add(k)
- q.append(k)
- for j in containedBoxes[i]:
- has.add(j)
- if status[j] and j not in took:
- ans += candies[j]
- took.add(j)
- q.append(j)
+ box = q.popleft()
+ for k in keys[box]:
+ if not status[k]:
+ status[k] = 1
+ if k in has and k not in took:
+ q.append(k)
+ took.add(k)
+ ans += candies[k]
+
+ for b in containedBoxes[box]:
+ has.add(b)
+ if status[b] and b not in took:
+ q.append(b)
+ took.add(b)
+ ans += candies[b]
return ans
diff --git a/solution/1200-1299/1298.Maximum Candies You Can Get from Boxes/Solution.rs b/solution/1200-1299/1298.Maximum Candies You Can Get from Boxes/Solution.rs
new file mode 100644
index 0000000000000..852f702b4d83e
--- /dev/null
+++ b/solution/1200-1299/1298.Maximum Candies You Can Get from Boxes/Solution.rs
@@ -0,0 +1,49 @@
+use std::collections::{HashSet, VecDeque};
+
+impl Solution {
+ pub fn max_candies(
+ mut status: Vec,
+ candies: Vec,
+ keys: Vec>,
+ contained_boxes: Vec>,
+ initial_boxes: Vec,
+ ) -> i32 {
+ let mut q: VecDeque = VecDeque::new();
+ let mut has: HashSet = HashSet::new();
+ let mut took: HashSet = HashSet::new();
+ let mut ans = 0;
+
+ for &box_ in &initial_boxes {
+ has.insert(box_);
+ if status[box_ as usize] == 1 {
+ q.push_back(box_);
+ took.insert(box_);
+ ans += candies[box_ as usize];
+ }
+ }
+
+ while let Some(box_) = q.pop_front() {
+ for &k in &keys[box_ as usize] {
+ if status[k as usize] == 0 {
+ status[k as usize] = 1;
+ if has.contains(&k) && !took.contains(&k) {
+ q.push_back(k);
+ took.insert(k);
+ ans += candies[k as usize];
+ }
+ }
+ }
+
+ for &b in &contained_boxes[box_ as usize] {
+ has.insert(b);
+ if status[b as usize] == 1 && !took.contains(&b) {
+ q.push_back(b);
+ took.insert(b);
+ ans += candies[b as usize];
+ }
+ }
+ }
+
+ ans
+ }
+}
diff --git a/solution/1200-1299/1298.Maximum Candies You Can Get from Boxes/Solution.ts b/solution/1200-1299/1298.Maximum Candies You Can Get from Boxes/Solution.ts
new file mode 100644
index 0000000000000..4a6b7feaa674e
--- /dev/null
+++ b/solution/1200-1299/1298.Maximum Candies You Can Get from Boxes/Solution.ts
@@ -0,0 +1,47 @@
+function maxCandies(
+ status: number[],
+ candies: number[],
+ keys: number[][],
+ containedBoxes: number[][],
+ initialBoxes: number[],
+): number {
+ const q: number[] = [];
+ const has: Set = new Set();
+ const took: Set = new Set();
+ let ans = 0;
+
+ for (const box of initialBoxes) {
+ has.add(box);
+ if (status[box] === 1) {
+ q.push(box);
+ took.add(box);
+ ans += candies[box];
+ }
+ }
+
+ while (q.length > 0) {
+ const box = q.pop()!;
+
+ for (const k of keys[box]) {
+ if (status[k] === 0) {
+ status[k] = 1;
+ if (has.has(k) && !took.has(k)) {
+ q.push(k);
+ took.add(k);
+ ans += candies[k];
+ }
+ }
+ }
+
+ for (const b of containedBoxes[box]) {
+ has.add(b);
+ if (status[b] === 1 && !took.has(b)) {
+ q.push(b);
+ took.add(b);
+ ans += candies[b];
+ }
+ }
+ }
+
+ return ans;
+}
diff --git a/solution/1300-1399/1301.Number of Paths with Max Score/README_EN.md b/solution/1300-1399/1301.Number of Paths with Max Score/README_EN.md
index e9ae14167981a..42f8aab8492d8 100644
--- a/solution/1300-1399/1301.Number of Paths with Max Score/README_EN.md
+++ b/solution/1300-1399/1301.Number of Paths with Max Score/README_EN.md
@@ -29,21 +29,35 @@ tags:
In case there is no path, return [0, 0]
.
+
Example 1:
+
Input: board = ["E23","2X2","12S"]
+
Output: [7,1]
+
Example 2:
+
Input: board = ["E12","1X1","21S"]
+
Output: [4,2]
+
Example 3:
+
Input: board = ["E11","XXX","11S"]
+
Output: [0,0]
+
+
+
Constraints:
- 2 <= board.length == board[i].length <= 100
+
+ 2 <= board.length == board[i].length <= 100
+
diff --git a/solution/1300-1399/1318.Minimum Flips to Make a OR b Equal to c/README_EN.md b/solution/1300-1399/1318.Minimum Flips to Make a OR b Equal to c/README_EN.md
index 25cf3e136deec..5d94e91fb76df 100644
--- a/solution/1300-1399/1318.Minimum Flips to Make a OR b Equal to c/README_EN.md
+++ b/solution/1300-1399/1318.Minimum Flips to Make a OR b Equal to c/README_EN.md
@@ -19,39 +19,55 @@ tags:
Given 3 positives numbers a
, b
and c
. Return the minimum flips required in some bits of a
and b
to make ( a
OR b
== c
). (bitwise OR operation).
+
Flip operation consists of change any single bit 1 to 0 or change the bit 0 to 1 in their binary representation.
+
Example 1:

+
Input: a = 2, b = 6, c = 5
+
Output: 3
+
Explanation: After flips a = 1 , b = 4 , c = 5 such that (a
OR b
== c
)
Example 2:
+
Input: a = 4, b = 2, c = 7
+
Output: 1
+
Example 3:
+
Input: a = 1, b = 2, c = 3
+
Output: 0
+
+
Constraints:
- 1 <= a <= 10^9
- 1 <= b <= 10^9
- 1 <= c <= 10^9
+
+ 1 <= a <= 10^9
+
+ 1 <= b <= 10^9
+
+ 1 <= c <= 10^9
+
diff --git a/solution/1300-1399/1324.Print Words Vertically/README_EN.md b/solution/1300-1399/1324.Print Words Vertically/README_EN.md
index e1542d061c72f..c86ec25b2c2cb 100644
--- a/solution/1300-1399/1324.Print Words Vertically/README_EN.md
+++ b/solution/1300-1399/1324.Print Words Vertically/README_EN.md
@@ -21,46 +21,71 @@ tags:
Given a string s
. Return all the words vertically in the same order in which they appear in s
.
+
Words are returned as a list of strings, complete with spaces when is necessary. (Trailing spaces are not allowed).
+
Each word would be put on only one column and that in one column there will be only one word.
+
Example 1:
+
Input: s = "HOW ARE YOU"
+
Output: ["HAY","ORO","WEU"]
+
Explanation: Each word is printed vertically.
+
"HAY"
+
"ORO"
+
"WEU"
+
Example 2:
+
Input: s = "TO BE OR NOT TO BE"
+
Output: ["TBONTB","OEROOE"," T"]
+
Explanation: Trailing spaces is not allowed.
+
"TBONTB"
+
"OEROOE"
+
" T"
+
Example 3:
+
Input: s = "CONTEST IS COMING"
+
Output: ["CIC","OSO","N M","T I","E N","S G","T"]
+
+
Constraints:
- 1 <= s.length <= 200
- s
contains only upper case English letters.
- - It's guaranteed that there is only one space between 2 words.
+
+ 1 <= s.length <= 200
+
+ s
contains only upper case English letters.
+
+ - It's guaranteed that there is only one space between 2 words.
+
diff --git a/solution/1300-1399/1334.Find the City With the Smallest Number of Neighbors at a Threshold Distance/README.md b/solution/1300-1399/1334.Find the City With the Smallest Number of Neighbors at a Threshold Distance/README.md
index 20c633d1c9fe2..83f740df319b5 100644
--- a/solution/1300-1399/1334.Find the City With the Smallest Number of Neighbors at a Threshold Distance/README.md
+++ b/solution/1300-1399/1334.Find the City With the Smallest Number of Neighbors at a Threshold Distance/README.md
@@ -30,7 +30,7 @@ tags:
示例 1:
-
+
输入:n = 4, edges = [[0,1,3],[1,2,1],[1,3,4],[2,3,1]], distanceThreshold = 4
@@ -46,7 +46,7 @@ tags:
示例 2:
-
+
输入:n = 5, edges = [[0,1,2],[0,4,8],[1,2,3],[1,4,2],[2,3,1],[3,4,1]], distanceThreshold = 2
diff --git a/solution/1300-1399/1340.Jump Game V/README.md b/solution/1300-1399/1340.Jump Game V/README.md
index 0660b49704759..b51d004488eaa 100644
--- a/solution/1300-1399/1340.Jump Game V/README.md
+++ b/solution/1300-1399/1340.Jump Game V/README.md
@@ -280,9 +280,7 @@ class Solution {
public int maxJumps(int[] arr, int d) {
int n = arr.length;
Integer[] idx = new Integer[n];
- for (int i = 0; i < n; ++i) {
- idx[i] = i;
- }
+ Arrays.setAll(idx, i -> i);
Arrays.sort(idx, (i, j) -> arr[i] - arr[j]);
int[] f = new int[n];
Arrays.fill(f, 1);
diff --git a/solution/1300-1399/1340.Jump Game V/README_EN.md b/solution/1300-1399/1340.Jump Game V/README_EN.md
index 96a1c9e3a29e9..d502c5e896373 100644
--- a/solution/1300-1399/1340.Jump Game V/README_EN.md
+++ b/solution/1300-1399/1340.Jump Game V/README_EN.md
@@ -251,9 +251,7 @@ class Solution {
public int maxJumps(int[] arr, int d) {
int n = arr.length;
Integer[] idx = new Integer[n];
- for (int i = 0; i < n; ++i) {
- idx[i] = i;
- }
+ Arrays.setAll(idx, i -> i);
Arrays.sort(idx, (i, j) -> arr[i] - arr[j]);
int[] f = new int[n];
Arrays.fill(f, 1);
diff --git a/solution/1300-1399/1340.Jump Game V/Solution2.java b/solution/1300-1399/1340.Jump Game V/Solution2.java
index 7eadbd4bb0a0a..9dd9b724cefe3 100644
--- a/solution/1300-1399/1340.Jump Game V/Solution2.java
+++ b/solution/1300-1399/1340.Jump Game V/Solution2.java
@@ -2,9 +2,7 @@ class Solution {
public int maxJumps(int[] arr, int d) {
int n = arr.length;
Integer[] idx = new Integer[n];
- for (int i = 0; i < n; ++i) {
- idx[i] = i;
- }
+ Arrays.setAll(idx, i -> i);
Arrays.sort(idx, (i, j) -> arr[i] - arr[j]);
int[] f = new int[n];
Arrays.fill(f, 1);
diff --git a/solution/1300-1399/1353.Maximum Number of Events That Can Be Attended/README.md b/solution/1300-1399/1353.Maximum Number of Events That Can Be Attended/README.md
index 1cbd1775a10f1..350c5c527eb1d 100644
--- a/solution/1300-1399/1353.Maximum Number of Events That Can Be Attended/README.md
+++ b/solution/1300-1399/1353.Maximum Number of Events That Can Be Attended/README.md
@@ -68,13 +68,17 @@ tags:
### 方法一:哈希表 + 贪心 + 优先队列
-定义哈希表记录每个会议的开始和结束时间,其中键为会议开始时间,值为结束时间列表。
+我们用一个哈希表 $\textit{g}$ 记录每个会议的开始和结束时间。键为会议的开始时间,值为一个列表,包含所有在该开始时间开始的会议的结束时间。用两个变量 $\textit{l}$ 和 $\textit{r}$ 分别记录会议的最小开始时间和最大结束时间。
-枚举当前时间 $s$,找出所有开始时间等于当前时间的会议,将其结束时间加入优先队列(小根堆)中。同时,优先队列要移除所有结束时间小于当前时间的会议。
+对于从小到大每个在 $\textit{l}$ 到 $\textit{r}$ 的时间点 $s$,我们需要做以下操作:
-然后从优先队列中取出结束时间最小的会议,即为当前时间可以参加的会议,累加答案数。如果优先队列为空,则说明当前时间没有可以参加的会议。
+1. 从优先队列中移除所有结束时间小于当前时间 $s$ 的会议。
+2. 将所有开始时间等于当前时间 $s$ 的会议的结束时间加入优先队列中。
+3. 如果优先队列不为空,则取出结束时间最小的会议,累加答案数,并从优先队列中移除该会议。
-时间复杂度 $O(m \times \log n)$,空间复杂度 $O(n)$。其中 $m$, $n$ 分别表示会议的最大结束时间,以及会议的数量。
+这样,我们可以确保在每个时间点 $s$,我们都能参加结束时间最早的会议,从而最大化参加的会议数。
+
+时间复杂度 $O(M \times \log n)$,空间复杂度 $O(n)$,其中 $M$ 和 $n$ 分别为会议的最大结束时间和会议的数量。
@@ -83,22 +87,22 @@ tags:
```python
class Solution:
def maxEvents(self, events: List[List[int]]) -> int:
- d = defaultdict(list)
- i, j = inf, 0
+ g = defaultdict(list)
+ l, r = inf, 0
for s, e in events:
- d[s].append(e)
- i = min(i, s)
- j = max(j, e)
- h = []
+ g[s].append(e)
+ l = min(l, s)
+ r = max(r, e)
+ pq = []
ans = 0
- for s in range(i, j + 1):
- while h and h[0] < s:
- heappop(h)
- for e in d[s]:
- heappush(h, e)
- if h:
+ for s in range(l, r + 1):
+ while pq and pq[0] < s:
+ heappop(pq)
+ for e in g[s]:
+ heappush(pq, e)
+ if pq:
+ heappop(pq)
ans += 1
- heappop(h)
return ans
```
@@ -107,26 +111,26 @@ class Solution:
```java
class Solution {
public int maxEvents(int[][] events) {
- Map> d = new HashMap<>();
- int i = Integer.MAX_VALUE, j = 0;
- for (var v : events) {
- int s = v[0], e = v[1];
- d.computeIfAbsent(s, k -> new ArrayList<>()).add(e);
- i = Math.min(i, s);
- j = Math.max(j, e);
+ Map> g = new HashMap<>();
+ int l = Integer.MAX_VALUE, r = 0;
+ for (int[] event : events) {
+ int s = event[0], e = event[1];
+ g.computeIfAbsent(s, k -> new ArrayList<>()).add(e);
+ l = Math.min(l, s);
+ r = Math.max(r, e);
}
- PriorityQueue q = new PriorityQueue<>();
+ PriorityQueue pq = new PriorityQueue<>();
int ans = 0;
- for (int s = i; s <= j; ++s) {
- while (!q.isEmpty() && q.peek() < s) {
- q.poll();
+ for (int s = l; s <= r; s++) {
+ while (!pq.isEmpty() && pq.peek() < s) {
+ pq.poll();
}
- for (int e : d.getOrDefault(s, Collections.emptyList())) {
- q.offer(e);
+ for (int e : g.getOrDefault(s, List.of())) {
+ pq.offer(e);
}
- if (!q.isEmpty()) {
- q.poll();
- ++ans;
+ if (!pq.isEmpty()) {
+ pq.poll();
+ ans++;
}
}
return ans;
@@ -140,26 +144,26 @@ class Solution {
class Solution {
public:
int maxEvents(vector>& events) {
- unordered_map> d;
- int i = INT_MAX, j = 0;
- for (auto& v : events) {
- int s = v[0], e = v[1];
- d[s].push_back(e);
- i = min(i, s);
- j = max(j, e);
+ unordered_map> g;
+ int l = INT_MAX, r = 0;
+ for (auto& event : events) {
+ int s = event[0], e = event[1];
+ g[s].push_back(e);
+ l = min(l, s);
+ r = max(r, e);
}
- priority_queue, greater> q;
+ priority_queue, greater> pq;
int ans = 0;
- for (int s = i; s <= j; ++s) {
- while (q.size() && q.top() < s) {
- q.pop();
+ for (int s = l; s <= r; ++s) {
+ while (!pq.empty() && pq.top() < s) {
+ pq.pop();
}
- for (int e : d[s]) {
- q.push(e);
+ for (int e : g[s]) {
+ pq.push(e);
}
- if (q.size()) {
+ if (!pq.empty()) {
+ pq.pop();
++ans;
- q.pop();
}
}
return ans;
@@ -170,44 +174,123 @@ public:
#### Go
```go
-func maxEvents(events [][]int) int {
- d := map[int][]int{}
- i, j := math.MaxInt32, 0
- for _, v := range events {
- s, e := v[0], v[1]
- d[s] = append(d[s], e)
- i = min(i, s)
- j = max(j, e)
+func maxEvents(events [][]int) (ans int) {
+ g := map[int][]int{}
+ l, r := math.MaxInt32, 0
+ for _, event := range events {
+ s, e := event[0], event[1]
+ g[s] = append(g[s], e)
+ l = min(l, s)
+ r = max(r, e)
}
- q := hp{}
- ans := 0
- for s := i; s <= j; s++ {
- for q.Len() > 0 && q.IntSlice[0] < s {
- heap.Pop(&q)
+
+ pq := &hp{}
+ heap.Init(pq)
+ for s := l; s <= r; s++ {
+ for pq.Len() > 0 && pq.IntSlice[0] < s {
+ heap.Pop(pq)
}
- for _, e := range d[s] {
- heap.Push(&q, e)
+ for _, e := range g[s] {
+ heap.Push(pq, e)
}
- if q.Len() > 0 {
- heap.Pop(&q)
+ if pq.Len() > 0 {
+ heap.Pop(pq)
ans++
}
}
- return ans
+ return
}
type hp struct{ sort.IntSlice }
func (h *hp) Push(v any) { h.IntSlice = append(h.IntSlice, v.(int)) }
func (h *hp) Pop() any {
- a := h.IntSlice
- v := a[len(a)-1]
- h.IntSlice = a[:len(a)-1]
+ n := len(h.IntSlice)
+ v := h.IntSlice[n-1]
+ h.IntSlice = h.IntSlice[:n-1]
return v
}
func (h *hp) Less(i, j int) bool { return h.IntSlice[i] < h.IntSlice[j] }
```
+#### TypeScript
+
+```ts
+function maxEvents(events: number[][]): number {
+ const g: Map = new Map();
+ let l = Infinity,
+ r = 0;
+ for (const [s, e] of events) {
+ if (!g.has(s)) g.set(s, []);
+ g.get(s)!.push(e);
+ l = Math.min(l, s);
+ r = Math.max(r, e);
+ }
+
+ const pq = new MinPriorityQueue();
+ let ans = 0;
+ for (let s = l; s <= r; s++) {
+ while (!pq.isEmpty() && pq.front() < s) {
+ pq.dequeue();
+ }
+ for (const e of g.get(s) || []) {
+ pq.enqueue(e);
+ }
+ if (!pq.isEmpty()) {
+ pq.dequeue();
+ ans++;
+ }
+ }
+ return ans;
+}
+```
+
+#### Rust
+
+```rust
+use std::collections::{BinaryHeap, HashMap};
+use std::cmp::Reverse;
+
+impl Solution {
+ pub fn max_events(events: Vec>) -> i32 {
+ let mut g: HashMap> = HashMap::new();
+ let mut l = i32::MAX;
+ let mut r = 0;
+
+ for event in events {
+ let s = event[0];
+ let e = event[1];
+ g.entry(s).or_default().push(e);
+ l = l.min(s);
+ r = r.max(e);
+ }
+
+ let mut pq = BinaryHeap::new();
+ let mut ans = 0;
+
+ for s in l..=r {
+ while let Some(&Reverse(top)) = pq.peek() {
+ if top < s {
+ pq.pop();
+ } else {
+ break;
+ }
+ }
+ if let Some(ends) = g.get(&s) {
+ for &e in ends {
+ pq.push(Reverse(e));
+ }
+ }
+ if pq.pop().is_some() {
+ ans += 1;
+ }
+ }
+
+ ans
+ }
+}
+```
+
diff --git a/solution/1300-1399/1353.Maximum Number of Events That Can Be Attended/README_EN.md b/solution/1300-1399/1353.Maximum Number of Events That Can Be Attended/README_EN.md
index 42234ff46dddb..9957c486820dd 100644
--- a/solution/1300-1399/1353.Maximum Number of Events That Can Be Attended/README_EN.md
+++ b/solution/1300-1399/1353.Maximum Number of Events That Can Be Attended/README_EN.md
@@ -23,7 +23,7 @@ tags:
You are given an array of events
where events[i] = [startDayi, endDayi]
. Every event i
starts at startDayi
and ends at endDayi
.
-You can attend an event i
at any day d
where startTimei <= d <= endTimei
. You can only attend one event at any time d
.
+You can attend an event i
at any day d
where startDayi <= d <= endDayi
. You can only attend one event at any time d
.
Return the maximum number of events you can attend.
@@ -64,13 +64,17 @@ Attend the third event on day 3.
### Solution 1: Hash Table + Greedy + Priority Queue
-Define a hash table to record the start and end times of each meeting, where the key is the start time of the meeting, and the value is a list of end times.
+We use a hash table $\textit{g}$ to record the start and end times of each event. The key is the start time of the event, and the value is a list containing the end times of all events that start at that time. Two variables, $\textit{l}$ and $\textit{r}$, are used to record the minimum start time and the maximum end time among all events.
-Enumerate the current time $s$, find all meetings that start at the current time, and add their end times to the priority queue (min heap). At the same time, the priority queue needs to remove all meetings that end before the current time.
+For each time point $s$ from $\textit{l}$ to $\textit{r}$ in increasing order, we perform the following steps:
-Then, take out the meeting with the smallest end time from the priority queue, which is the meeting that can be attended at the current time, and accumulate the answer count. If the priority queue is empty, it means that there are no meetings that can be attended at the current time.
+1. Remove from the priority queue all events whose end time is less than the current time $s$.
+2. Add the end times of all events that start at the current time $s$ to the priority queue.
+3. If the priority queue is not empty, take out the event with the earliest end time, increment the answer count, and remove this event from the priority queue.
-The time complexity is $O(m \times \log n)$, and the space complexity is $O(n)$. Where $m$ and $n$ represent the maximum end time of the meetings and the number of meetings, respectively.
+In this way, we ensure that at each time point $s$, we always attend the event that ends the earliest, thus maximizing the number of events attended.
+
+The time complexity is $O(M \times \log n)$, and the space complexity is $O(n)$, where $M$ is the maximum end time and $n$ is the number of events.
@@ -79,22 +83,22 @@ The time complexity is $O(m \times \log n)$, and the space complexity is $O(n)$.
```python
class Solution:
def maxEvents(self, events: List[List[int]]) -> int:
- d = defaultdict(list)
- i, j = inf, 0
+ g = defaultdict(list)
+ l, r = inf, 0
for s, e in events:
- d[s].append(e)
- i = min(i, s)
- j = max(j, e)
- h = []
+ g[s].append(e)
+ l = min(l, s)
+ r = max(r, e)
+ pq = []
ans = 0
- for s in range(i, j + 1):
- while h and h[0] < s:
- heappop(h)
- for e in d[s]:
- heappush(h, e)
- if h:
+ for s in range(l, r + 1):
+ while pq and pq[0] < s:
+ heappop(pq)
+ for e in g[s]:
+ heappush(pq, e)
+ if pq:
+ heappop(pq)
ans += 1
- heappop(h)
return ans
```
@@ -103,26 +107,26 @@ class Solution:
```java
class Solution {
public int maxEvents(int[][] events) {
- Map> d = new HashMap<>();
- int i = Integer.MAX_VALUE, j = 0;
- for (var v : events) {
- int s = v[0], e = v[1];
- d.computeIfAbsent(s, k -> new ArrayList<>()).add(e);
- i = Math.min(i, s);
- j = Math.max(j, e);
+ Map> g = new HashMap<>();
+ int l = Integer.MAX_VALUE, r = 0;
+ for (int[] event : events) {
+ int s = event[0], e = event[1];
+ g.computeIfAbsent(s, k -> new ArrayList<>()).add(e);
+ l = Math.min(l, s);
+ r = Math.max(r, e);
}
- PriorityQueue q = new PriorityQueue<>();
+ PriorityQueue pq = new PriorityQueue<>();
int ans = 0;
- for (int s = i; s <= j; ++s) {
- while (!q.isEmpty() && q.peek() < s) {
- q.poll();
+ for (int s = l; s <= r; s++) {
+ while (!pq.isEmpty() && pq.peek() < s) {
+ pq.poll();
}
- for (int e : d.getOrDefault(s, Collections.emptyList())) {
- q.offer(e);
+ for (int e : g.getOrDefault(s, List.of())) {
+ pq.offer(e);
}
- if (!q.isEmpty()) {
- q.poll();
- ++ans;
+ if (!pq.isEmpty()) {
+ pq.poll();
+ ans++;
}
}
return ans;
@@ -136,26 +140,26 @@ class Solution {
class Solution {
public:
int maxEvents(vector>& events) {
- unordered_map> d;
- int i = INT_MAX, j = 0;
- for (auto& v : events) {
- int s = v[0], e = v[1];
- d[s].push_back(e);
- i = min(i, s);
- j = max(j, e);
+ unordered_map> g;
+ int l = INT_MAX, r = 0;
+ for (auto& event : events) {
+ int s = event[0], e = event[1];
+ g[s].push_back(e);
+ l = min(l, s);
+ r = max(r, e);
}
- priority_queue, greater> q;
+ priority_queue, greater> pq;
int ans = 0;
- for (int s = i; s <= j; ++s) {
- while (q.size() && q.top() < s) {
- q.pop();
+ for (int s = l; s <= r; ++s) {
+ while (!pq.empty() && pq.top() < s) {
+ pq.pop();
}
- for (int e : d[s]) {
- q.push(e);
+ for (int e : g[s]) {
+ pq.push(e);
}
- if (q.size()) {
+ if (!pq.empty()) {
+ pq.pop();
++ans;
- q.pop();
}
}
return ans;
@@ -166,44 +170,123 @@ public:
#### Go
```go
-func maxEvents(events [][]int) int {
- d := map[int][]int{}
- i, j := math.MaxInt32, 0
- for _, v := range events {
- s, e := v[0], v[1]
- d[s] = append(d[s], e)
- i = min(i, s)
- j = max(j, e)
+func maxEvents(events [][]int) (ans int) {
+ g := map[int][]int{}
+ l, r := math.MaxInt32, 0
+ for _, event := range events {
+ s, e := event[0], event[1]
+ g[s] = append(g[s], e)
+ l = min(l, s)
+ r = max(r, e)
}
- q := hp{}
- ans := 0
- for s := i; s <= j; s++ {
- for q.Len() > 0 && q.IntSlice[0] < s {
- heap.Pop(&q)
+
+ pq := &hp{}
+ heap.Init(pq)
+ for s := l; s <= r; s++ {
+ for pq.Len() > 0 && pq.IntSlice[0] < s {
+ heap.Pop(pq)
}
- for _, e := range d[s] {
- heap.Push(&q, e)
+ for _, e := range g[s] {
+ heap.Push(pq, e)
}
- if q.Len() > 0 {
- heap.Pop(&q)
+ if pq.Len() > 0 {
+ heap.Pop(pq)
ans++
}
}
- return ans
+ return
}
type hp struct{ sort.IntSlice }
func (h *hp) Push(v any) { h.IntSlice = append(h.IntSlice, v.(int)) }
func (h *hp) Pop() any {
- a := h.IntSlice
- v := a[len(a)-1]
- h.IntSlice = a[:len(a)-1]
+ n := len(h.IntSlice)
+ v := h.IntSlice[n-1]
+ h.IntSlice = h.IntSlice[:n-1]
return v
}
func (h *hp) Less(i, j int) bool { return h.IntSlice[i] < h.IntSlice[j] }
```
+#### TypeScript
+
+```ts
+function maxEvents(events: number[][]): number {
+ const g: Map = new Map();
+ let l = Infinity,
+ r = 0;
+ for (const [s, e] of events) {
+ if (!g.has(s)) g.set(s, []);
+ g.get(s)!.push(e);
+ l = Math.min(l, s);
+ r = Math.max(r, e);
+ }
+
+ const pq = new MinPriorityQueue();
+ let ans = 0;
+ for (let s = l; s <= r; s++) {
+ while (!pq.isEmpty() && pq.front() < s) {
+ pq.dequeue();
+ }
+ for (const e of g.get(s) || []) {
+ pq.enqueue(e);
+ }
+ if (!pq.isEmpty()) {
+ pq.dequeue();
+ ans++;
+ }
+ }
+ return ans;
+}
+```
+
+#### Rust
+
+```rust
+use std::collections::{BinaryHeap, HashMap};
+use std::cmp::Reverse;
+
+impl Solution {
+ pub fn max_events(events: Vec>) -> i32 {
+ let mut g: HashMap> = HashMap::new();
+ let mut l = i32::MAX;
+ let mut r = 0;
+
+ for event in events {
+ let s = event[0];
+ let e = event[1];
+ g.entry(s).or_default().push(e);
+ l = l.min(s);
+ r = r.max(e);
+ }
+
+ let mut pq = BinaryHeap::new();
+ let mut ans = 0;
+
+ for s in l..=r {
+ while let Some(&Reverse(top)) = pq.peek() {
+ if top < s {
+ pq.pop();
+ } else {
+ break;
+ }
+ }
+ if let Some(ends) = g.get(&s) {
+ for &e in ends {
+ pq.push(Reverse(e));
+ }
+ }
+ if pq.pop().is_some() {
+ ans += 1;
+ }
+ }
+
+ ans
+ }
+}
+```
+
diff --git a/solution/1300-1399/1353.Maximum Number of Events That Can Be Attended/Solution.cpp b/solution/1300-1399/1353.Maximum Number of Events That Can Be Attended/Solution.cpp
index b606f12f54a94..bff232aed16a4 100644
--- a/solution/1300-1399/1353.Maximum Number of Events That Can Be Attended/Solution.cpp
+++ b/solution/1300-1399/1353.Maximum Number of Events That Can Be Attended/Solution.cpp
@@ -1,28 +1,28 @@
class Solution {
public:
int maxEvents(vector>& events) {
- unordered_map> d;
- int i = INT_MAX, j = 0;
- for (auto& v : events) {
- int s = v[0], e = v[1];
- d[s].push_back(e);
- i = min(i, s);
- j = max(j, e);
+ unordered_map> g;
+ int l = INT_MAX, r = 0;
+ for (auto& event : events) {
+ int s = event[0], e = event[1];
+ g[s].push_back(e);
+ l = min(l, s);
+ r = max(r, e);
}
- priority_queue, greater> q;
+ priority_queue, greater> pq;
int ans = 0;
- for (int s = i; s <= j; ++s) {
- while (q.size() && q.top() < s) {
- q.pop();
+ for (int s = l; s <= r; ++s) {
+ while (!pq.empty() && pq.top() < s) {
+ pq.pop();
}
- for (int e : d[s]) {
- q.push(e);
+ for (int e : g[s]) {
+ pq.push(e);
}
- if (q.size()) {
+ if (!pq.empty()) {
+ pq.pop();
++ans;
- q.pop();
}
}
return ans;
}
-};
\ No newline at end of file
+};
diff --git a/solution/1300-1399/1353.Maximum Number of Events That Can Be Attended/Solution.go b/solution/1300-1399/1353.Maximum Number of Events That Can Be Attended/Solution.go
index df48690182d72..1b5722cd4a3a2 100644
--- a/solution/1300-1399/1353.Maximum Number of Events That Can Be Attended/Solution.go
+++ b/solution/1300-1399/1353.Maximum Number of Events That Can Be Attended/Solution.go
@@ -1,36 +1,37 @@
-func maxEvents(events [][]int) int {
- d := map[int][]int{}
- i, j := math.MaxInt32, 0
- for _, v := range events {
- s, e := v[0], v[1]
- d[s] = append(d[s], e)
- i = min(i, s)
- j = max(j, e)
+func maxEvents(events [][]int) (ans int) {
+ g := map[int][]int{}
+ l, r := math.MaxInt32, 0
+ for _, event := range events {
+ s, e := event[0], event[1]
+ g[s] = append(g[s], e)
+ l = min(l, s)
+ r = max(r, e)
}
- q := hp{}
- ans := 0
- for s := i; s <= j; s++ {
- for q.Len() > 0 && q.IntSlice[0] < s {
- heap.Pop(&q)
+
+ pq := &hp{}
+ heap.Init(pq)
+ for s := l; s <= r; s++ {
+ for pq.Len() > 0 && pq.IntSlice[0] < s {
+ heap.Pop(pq)
}
- for _, e := range d[s] {
- heap.Push(&q, e)
+ for _, e := range g[s] {
+ heap.Push(pq, e)
}
- if q.Len() > 0 {
- heap.Pop(&q)
+ if pq.Len() > 0 {
+ heap.Pop(pq)
ans++
}
}
- return ans
+ return
}
type hp struct{ sort.IntSlice }
func (h *hp) Push(v any) { h.IntSlice = append(h.IntSlice, v.(int)) }
func (h *hp) Pop() any {
- a := h.IntSlice
- v := a[len(a)-1]
- h.IntSlice = a[:len(a)-1]
+ n := len(h.IntSlice)
+ v := h.IntSlice[n-1]
+ h.IntSlice = h.IntSlice[:n-1]
return v
}
-func (h *hp) Less(i, j int) bool { return h.IntSlice[i] < h.IntSlice[j] }
\ No newline at end of file
+func (h *hp) Less(i, j int) bool { return h.IntSlice[i] < h.IntSlice[j] }
diff --git a/solution/1300-1399/1353.Maximum Number of Events That Can Be Attended/Solution.java b/solution/1300-1399/1353.Maximum Number of Events That Can Be Attended/Solution.java
index 55ae438150200..f85ae216d53f4 100644
--- a/solution/1300-1399/1353.Maximum Number of Events That Can Be Attended/Solution.java
+++ b/solution/1300-1399/1353.Maximum Number of Events That Can Be Attended/Solution.java
@@ -1,27 +1,27 @@
class Solution {
public int maxEvents(int[][] events) {
- Map> d = new HashMap<>();
- int i = Integer.MAX_VALUE, j = 0;
- for (var v : events) {
- int s = v[0], e = v[1];
- d.computeIfAbsent(s, k -> new ArrayList<>()).add(e);
- i = Math.min(i, s);
- j = Math.max(j, e);
+ Map> g = new HashMap<>();
+ int l = Integer.MAX_VALUE, r = 0;
+ for (int[] event : events) {
+ int s = event[0], e = event[1];
+ g.computeIfAbsent(s, k -> new ArrayList<>()).add(e);
+ l = Math.min(l, s);
+ r = Math.max(r, e);
}
- PriorityQueue q = new PriorityQueue<>();
+ PriorityQueue pq = new PriorityQueue<>();
int ans = 0;
- for (int s = i; s <= j; ++s) {
- while (!q.isEmpty() && q.peek() < s) {
- q.poll();
+ for (int s = l; s <= r; s++) {
+ while (!pq.isEmpty() && pq.peek() < s) {
+ pq.poll();
}
- for (int e : d.getOrDefault(s, Collections.emptyList())) {
- q.offer(e);
+ for (int e : g.getOrDefault(s, List.of())) {
+ pq.offer(e);
}
- if (!q.isEmpty()) {
- q.poll();
- ++ans;
+ if (!pq.isEmpty()) {
+ pq.poll();
+ ans++;
}
}
return ans;
}
-}
\ No newline at end of file
+}
diff --git a/solution/1300-1399/1353.Maximum Number of Events That Can Be Attended/Solution.py b/solution/1300-1399/1353.Maximum Number of Events That Can Be Attended/Solution.py
index c8f9fd352a5b7..0d32d73265ae6 100644
--- a/solution/1300-1399/1353.Maximum Number of Events That Can Be Attended/Solution.py
+++ b/solution/1300-1399/1353.Maximum Number of Events That Can Be Attended/Solution.py
@@ -1,19 +1,19 @@
class Solution:
def maxEvents(self, events: List[List[int]]) -> int:
- d = defaultdict(list)
- i, j = inf, 0
+ g = defaultdict(list)
+ l, r = inf, 0
for s, e in events:
- d[s].append(e)
- i = min(i, s)
- j = max(j, e)
- h = []
+ g[s].append(e)
+ l = min(l, s)
+ r = max(r, e)
+ pq = []
ans = 0
- for s in range(i, j + 1):
- while h and h[0] < s:
- heappop(h)
- for e in d[s]:
- heappush(h, e)
- if h:
+ for s in range(l, r + 1):
+ while pq and pq[0] < s:
+ heappop(pq)
+ for e in g[s]:
+ heappush(pq, e)
+ if pq:
+ heappop(pq)
ans += 1
- heappop(h)
return ans
diff --git a/solution/1300-1399/1353.Maximum Number of Events That Can Be Attended/Solution.rs b/solution/1300-1399/1353.Maximum Number of Events That Can Be Attended/Solution.rs
new file mode 100644
index 0000000000000..8655f8f45b8c3
--- /dev/null
+++ b/solution/1300-1399/1353.Maximum Number of Events That Can Be Attended/Solution.rs
@@ -0,0 +1,41 @@
+use std::cmp::Reverse;
+use std::collections::{BinaryHeap, HashMap};
+
+impl Solution {
+ pub fn max_events(events: Vec>) -> i32 {
+ let mut g: HashMap> = HashMap::new();
+ let mut l = i32::MAX;
+ let mut r = 0;
+
+ for event in events {
+ let s = event[0];
+ let e = event[1];
+ g.entry(s).or_default().push(e);
+ l = l.min(s);
+ r = r.max(e);
+ }
+
+ let mut pq = BinaryHeap::new();
+ let mut ans = 0;
+
+ for s in l..=r {
+ while let Some(&Reverse(top)) = pq.peek() {
+ if top < s {
+ pq.pop();
+ } else {
+ break;
+ }
+ }
+ if let Some(ends) = g.get(&s) {
+ for &e in ends {
+ pq.push(Reverse(e));
+ }
+ }
+ if pq.pop().is_some() {
+ ans += 1;
+ }
+ }
+
+ ans
+ }
+}
diff --git a/solution/1300-1399/1353.Maximum Number of Events That Can Be Attended/Solution.ts b/solution/1300-1399/1353.Maximum Number of Events That Can Be Attended/Solution.ts
new file mode 100644
index 0000000000000..fe09e3bbc62a7
--- /dev/null
+++ b/solution/1300-1399/1353.Maximum Number of Events That Can Be Attended/Solution.ts
@@ -0,0 +1,27 @@
+function maxEvents(events: number[][]): number {
+ const g: Map = new Map();
+ let l = Infinity,
+ r = 0;
+ for (const [s, e] of events) {
+ if (!g.has(s)) g.set(s, []);
+ g.get(s)!.push(e);
+ l = Math.min(l, s);
+ r = Math.max(r, e);
+ }
+
+ const pq = new MinPriorityQueue();
+ let ans = 0;
+ for (let s = l; s <= r; s++) {
+ while (!pq.isEmpty() && pq.front() < s) {
+ pq.dequeue();
+ }
+ for (const e of g.get(s) || []) {
+ pq.enqueue(e);
+ }
+ if (!pq.isEmpty()) {
+ pq.dequeue();
+ ans++;
+ }
+ }
+ return ans;
+}
diff --git a/solution/1300-1399/1354.Construct Target Array With Multiple Sums/README.md b/solution/1300-1399/1354.Construct Target Array With Multiple Sums/README.md
index 67cd7338f7ab9..92d70c41f8ff3 100644
--- a/solution/1300-1399/1354.Construct Target Array With Multiple Sums/README.md
+++ b/solution/1300-1399/1354.Construct Target Array With Multiple Sums/README.md
@@ -198,14 +198,14 @@ func (hp) Push(any) {}
```ts
function isPossible(target: number[]): boolean {
- const pq = new MaxPriorityQueue();
+ const pq = new MaxPriorityQueue();
let s = 0;
for (const x of target) {
s += x;
pq.enqueue(x);
}
- while (pq.front().element > 1) {
- const mx = pq.dequeue().element;
+ while (pq.front() > 1) {
+ const mx = pq.dequeue();
const t = s - mx;
if (t < 1 || mx - t < 1) {
return false;
diff --git a/solution/1300-1399/1354.Construct Target Array With Multiple Sums/README_EN.md b/solution/1300-1399/1354.Construct Target Array With Multiple Sums/README_EN.md
index 46c3cefe4351d..1add677cba9f6 100644
--- a/solution/1300-1399/1354.Construct Target Array With Multiple Sums/README_EN.md
+++ b/solution/1300-1399/1354.Construct Target Array With Multiple Sums/README_EN.md
@@ -199,14 +199,14 @@ func (hp) Push(any) {}
```ts
function isPossible(target: number[]): boolean {
- const pq = new MaxPriorityQueue();
+ const pq = new MaxPriorityQueue();
let s = 0;
for (const x of target) {
s += x;
pq.enqueue(x);
}
- while (pq.front().element > 1) {
- const mx = pq.dequeue().element;
+ while (pq.front() > 1) {
+ const mx = pq.dequeue();
const t = s - mx;
if (t < 1 || mx - t < 1) {
return false;
diff --git a/solution/1300-1399/1354.Construct Target Array With Multiple Sums/Solution.ts b/solution/1300-1399/1354.Construct Target Array With Multiple Sums/Solution.ts
index 144be716e511b..30f3e9d27db06 100644
--- a/solution/1300-1399/1354.Construct Target Array With Multiple Sums/Solution.ts
+++ b/solution/1300-1399/1354.Construct Target Array With Multiple Sums/Solution.ts
@@ -1,12 +1,12 @@
function isPossible(target: number[]): boolean {
- const pq = new MaxPriorityQueue();
+ const pq = new MaxPriorityQueue();
let s = 0;
for (const x of target) {
s += x;
pq.enqueue(x);
}
- while (pq.front().element > 1) {
- const mx = pq.dequeue().element;
+ while (pq.front() > 1) {
+ const mx = pq.dequeue();
const t = s - mx;
if (t < 1 || mx - t < 1) {
return false;
diff --git a/solution/1300-1399/1375.Number of Times Binary String Is Prefix-Aligned/README_EN.md b/solution/1300-1399/1375.Number of Times Binary String Is Prefix-Aligned/README_EN.md
index 85728f8ff86c4..6ee738a4c99d0 100644
--- a/solution/1300-1399/1375.Number of Times Binary String Is Prefix-Aligned/README_EN.md
+++ b/solution/1300-1399/1375.Number of Times Binary String Is Prefix-Aligned/README_EN.md
@@ -18,7 +18,7 @@ tags:
-