Skip to content

Commit e398ded

Browse files
committed
添加 problem 721、778、839、947、959 题解
1 parent 941f20c commit e398ded

File tree

5 files changed

+313
-0
lines changed

5 files changed

+313
-0
lines changed
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# [721. Accounts Merge](https://leetcode.com/problems/accounts-merge/)
2+
3+
4+
## 题目:
5+
6+
Given a list `accounts`, each element `accounts[i]` is a list of strings, where the first element `accounts[i][0]` is a name, and the rest of the elements are emailsrepresenting emails of the account.
7+
8+
Now, we would like to merge these accounts. Two accounts definitely belong to the same person if there is some email that is common to both accounts. Note that even if two accounts have the same name, they may belong to different people as people could have the same name. A person can have any number of accounts initially, but all of their accounts definitely have the same name.
9+
10+
After merging the accounts, return the accounts in the following format: the first element of each account is the name, and the rest of the elements are emails **in sorted order**. The accounts themselves can be returned in any order.
11+
12+
**Example 1:**
13+
14+
Input:
15+
accounts = [["John", "[email protected]", "[email protected]"], ["John", "[email protected]"], ["John", "[email protected]", "[email protected]"], ["Mary", "[email protected]"]]
16+
17+
Explanation:
18+
The first and third John's are the same person as they have the common email "[email protected]".
19+
The second John and Mary are different people as none of their email addresses are used by other accounts.
20+
We could return these lists in any order, for example the answer [['Mary', '[email protected]'], ['John', '[email protected]'],
21+
['John', '[email protected]', '[email protected]', '[email protected]']] would still be accepted.
22+
23+
**Note:**
24+
25+
- The length of `accounts` will be in the range `[1, 1000]`.
26+
- The length of `accounts[i]` will be in the range `[1, 10]`.
27+
- The length of `accounts[i][j]` will be in the range `[1, 30]`.
28+
29+
30+
## 题目大意
31+
32+
33+
给定一个列表 accounts,每个元素 accounts[i] 是一个字符串列表,其中第一个元素 accounts[i][0] 是 名称 (name),其余元素是 emails 表示该帐户的邮箱地址。现在,我们想合并这些帐户。如果两个帐户都有一些共同的邮件地址,则两个帐户必定属于同一个人。请注意,即使两个帐户具有相同的名称,它们也可能属于不同的人,因为人们可能具有相同的名称。一个人最初可以拥有任意数量的帐户,但其所有帐户都具有相同的名称。合并帐户后,按以下格式返回帐户:每个帐户的第一个元素是名称,其余元素是按顺序排列的邮箱地址。accounts 本身可以以任意顺序返回。
34+
35+
36+
注意:
37+
38+
- accounts 的长度将在 [1,1000] 的范围内。
39+
- accounts[i] 的长度将在 [1,10] 的范围内。
40+
- accounts[i][j] 的长度将在 [1,30] 的范围内。
41+
42+
43+
44+
## 解题思路
45+
46+
47+
- 给出一堆账户和对应的邮箱。要求合并同一个人的多个邮箱账户。如果判断是同一个人呢?如果这个人名和所属的其中之一的邮箱是相同的,就判定这是同一个人的邮箱,那么就合并这些邮箱。
48+
- 这题的解题思路是并查集。不过如果用暴力合并的方法,时间复杂度非常差。优化方法是先把每组数据都进行编号,人编号,每个邮箱都进行编号。这个映射关系用 `map` 记录起来。如果利用并查集的 `union()` 操作,把这些编号都进行合并。最后把人的编号和对应邮箱的编号拼接起来。
49+
- 这一题有 2 处比较“坑”的是,不需要合并的用户的邮箱列表也是需要排序和去重的,同一个人的所有邮箱集合都要合并到一起。具体见测试用例。不过题目中也提到了这些点,也不能算题目坑,只能归自己没注意这些边界情况。
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# [778. Swim in Rising Water](https://leetcode.com/problems/swim-in-rising-water/)
2+
3+
4+
## 题目:
5+
6+
On an N x N `grid`, each square `grid[i][j]` represents the elevation at that point `(i,j)`.
7+
8+
Now rain starts to fall. At time `t`, the depth of the water everywhere is `t`. You can swim from a square to another 4-directionally adjacent square if and only if the elevation of both squares individually are at most `t`. You can swim infinite distance in zero time. Of course, you must stay within the boundaries of the grid during your swim.
9+
10+
You start at the top left square `(0, 0)`. What is the least time until you can reach the bottom right square `(N-1, N-1)`?
11+
12+
**Example 1:**
13+
14+
Input: [[0,2],[1,3]]
15+
Output: 3
16+
Explanation:
17+
At time 0, you are in grid location (0, 0).
18+
You cannot go anywhere else because 4-directionally adjacent neighbors have a higher elevation than t = 0.
19+
20+
You cannot reach point (1, 1) until time 3.
21+
When the depth of water is 3, we can swim anywhere inside the grid.
22+
23+
**Example 2:**
24+
25+
Input: [[0,1,2,3,4],[24,23,22,21,5],[12,13,14,15,16],[11,17,18,19,20],[10,9,8,7,6]]
26+
Output: 16
27+
Explanation:
28+
0 1 2 3 4
29+
24 23 22 21 5
30+
12 13 14 15 16
31+
11 17 18 19 20
32+
10 9 8 7 6
33+
34+
The final route is marked in bold.
35+
We need to wait until time 16 so that (0, 0) and (4, 4) are connected.
36+
37+
**Note:**
38+
39+
1. `2 <= N <= 50`.
40+
2. grid[i][j] is a permutation of [0, ..., N*N - 1].
41+
42+
## 题目大意
43+
44+
45+
在一个 N x N 的坐标方格 grid 中,每一个方格的值 grid[i][j] 表示在位置 (i,j) 的平台高度。现在开始下雨了。当时间为 t 时,此时雨水导致水池中任意位置的水位为 t 。你可以从一个平台游向四周相邻的任意一个平台,但是前提是此时水位必须同时淹没这两个平台。假定你可以瞬间移动无限距离,也就是默认在方格内部游动是不耗时的。当然,在你游泳的时候你必须待在坐标方格里面。
46+
47+
你从坐标方格的左上平台 (0,0) 出发。最少耗时多久你才能到达坐标方格的右下平台 (N-1, N-1)?
48+
49+
提示:
50+
51+
- 2 <= N <= 50.
52+
- grid[i][j] 位于区间 [0, ..., N*N - 1] 内。
53+
54+
55+
## 解题思路
56+
57+
- 给出一个 grid[i][j] 方格,每个格子里面表示游泳池里面平台的高度。t 时刻,游泳池中的水的高度是 t。只有水的高度到达了平台的高度以后才能游过去。问从 (0,0) 开始,最短多长时间能到达 (N-1, N-1) 。
58+
- 这一题有多种解法。第一种解题思路是利用 DFS + 二分。DFS 是用来遍历是否可达。利用时间(即当前水淹过的高度)来判断是否能到达终点 (N-1, N-1) 点。二分用来搜索最终结果的时间。为什么会考虑用二分加速呢?原因是:时间从 0 - max 依次递增。max 是游泳池最高的平台高度。当时间从 0 增加到 max 以后,肯定能到达终点 (N-1, N-1) 点,因为水比所有平台都要高了。想快速找到一个时间 t 能使得 (0,0) 点和 (N-1, N-1) 点之间连通,那么就想到用二分加速了。判断是否取中值的条件是 (0,0) 点和 (N-1, N-1) 点之间是否连通。
59+
- 第二种解题思路是并查集。只要是 (0,0) 点和 (N-1, N-1) 点没有连通,即不能游到终点,那么就开始 `union()` 操作,由于起点是 (0,0),所以向右边 `i + 1` 和向下边 `j + 1` 开始尝试。每尝试完一轮,时间会加 1 秒,即高度会加一。直到 (0,0) 点和 (N-1, N-1) 点刚好连通,那么这个时间点就是最终要求的。
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# [839. Similar String Groups](https://leetcode.com/problems/similar-string-groups/)
2+
3+
4+
## 题目:
5+
6+
Two strings `X` and `Y` are similar if we can swap two letters (in different positions) of `X`, so that it equals `Y`.
7+
8+
For example, `"tars"` and `"rats"` are similar (swapping at positions `0` and `2`), and `"rats"` and `"arts"` are similar, but `"star"` is not similar to `"tars"``"rats"`, or `"arts"`.
9+
10+
Together, these form two connected groups by similarity: `{"tars", "rats", "arts"}` and `{"star"}`. Notice that `"tars"` and `"arts"` are in the same group even though they are not similar. Formally, each group is such that a word is in the group if and only if it is similar to at least one other word in the group.
11+
12+
We are given a list `A` of strings. Every string in `A` is an anagram of every other string in `A`. How many groups are there?
13+
14+
**Example 1:**
15+
16+
Input: ["tars","rats","arts","star"]
17+
Output: 2
18+
19+
**Note:**
20+
21+
1. `A.length <= 2000`
22+
2. `A[i].length <= 1000`
23+
3. `A.length * A[i].length <= 20000`
24+
4. All words in `A` consist of lowercase letters only.
25+
5. All words in `A` have the same length and are anagrams of each other.
26+
6. The judging time limit has been increased for this question.
27+
28+
29+
## 题目大意
30+
31+
如果我们交换字符串 X 中的两个不同位置的字母,使得它和字符串 Y 相等,那么称 X 和 Y 两个字符串相似。
32+
33+
例如,"tars" 和 "rats" 是相似的 (交换 0 与 2 的位置); "rats" 和 "arts" 也是相似的,但是 "star" 不与 "tars","rats",或 "arts" 相似。
34+
35+
总之,它们通过相似性形成了两个关联组:{"tars", "rats", "arts"} 和 {"star"}。注意,"tars" 和 "arts" 是在同一组中,即使它们并不相似。形式上,对每个组而言,要确定一个单词在组中,只需要这个词和该组中至少一个单词相似。我们给出了一个不包含重复的字符串列表 A。列表中的每个字符串都是 A 中其它所有字符串的一个字母异位词。请问 A 中有多少个相似字符串组?
36+
37+
38+
提示:
39+
40+
- A.length <= 2000
41+
- A[i].length <= 1000
42+
- A.length * A[i].length <= 20000
43+
- A 中的所有单词都只包含小写字母。
44+
- A 中的所有单词都具有相同的长度,且是彼此的字母异位词。
45+
- 此问题的判断限制时间已经延长。
46+
47+
48+
备注:
49+
50+
- 字母异位词[anagram],一种把某个字符串的字母的位置(顺序)加以改换所形成的新词。
51+
52+
53+
54+
55+
## 解题思路
56+
57+
58+
- 给出一个字符串数组,要求找出这个数组中,"不相似"的字符串有多少种。相似的字符串的定义是:如果 A 和 B 字符串只需要交换一次字母的位置就能变成两个相等的字符串,那么 A 和 B 是相似的。
59+
- 这一题的解题思路是用并查集。先将题目中的“相似”的定义转换一下,A 和 B 相似的意思是,A 和 B 中只有 2 个字符不相等,其他字符都相等,这样交换一次才能完全相等。有没有可能这两个字符交换了也不相等呢?这种情况不用考虑,因为题目中提到了给的字符串都是 `anagram` 的(`anagram` 的意思是,字符串的任意排列组合)。那么这题就比较简单了,只需要判断每两个字符串是否“相似”,如果相似就 `union()`,最后看并查集中有几个集合即可。
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# [947. Most Stones Removed with Same Row or Column](https://leetcode.com/problems/most-stones-removed-with-same-row-or-column/)
2+
3+
4+
## 题目:
5+
6+
On a 2D plane, we place stones at some integer coordinate points. Each coordinate point may have at most one stone.
7+
8+
Now, a *move* consists of removing a stone that shares a column or row with another stone on the grid.
9+
10+
What is the largest possible number of moves we can make?
11+
12+
**Example 1:**
13+
14+
Input: stones = [[0,0],[0,1],[1,0],[1,2],[2,1],[2,2]]
15+
Output: 5
16+
17+
**Example 2:**
18+
19+
Input: stones = [[0,0],[0,2],[1,1],[2,0],[2,2]]
20+
Output: 3
21+
22+
**Example 3:**
23+
24+
Input: stones = [[0,0]]
25+
Output: 0
26+
27+
**Note:**
28+
29+
1. `1 <= stones.length <= 1000`
30+
2. `0 <= stones[i][j] < 10000`
31+
32+
33+
## 题目大意
34+
35+
在二维平面上,我们将石头放置在一些整数坐标点上。每个坐标点上最多只能有一块石头。现在,move 操作将会移除与网格上的某一块石头共享一列或一行的一块石头。我们最多能执行多少次 move 操作?
36+
37+
提示:
38+
39+
- 1 <= stones.length <= 1000
40+
- 0 <= stones[i][j] < 10000
41+
42+
43+
## 解题思路
44+
45+
46+
- 给出一个数组,数组中的元素是一系列的坐标点。现在可以移除一些坐标点,移除必须满足:移除的这个点,在相同的行或者列上有一个点。问最终可以移除多少个点。移除到最后必然有些点独占一行,那么这些点都不能被移除。
47+
- 这一题的解题思路是并查集。把所有共行或者共列的点都 `union()` 起来。不同集合之间是不能相互移除的。反证法:如果能移除,代表存在共行或者共列的情况,那么肯定是同一个集合了,这样就不满足不同集合了。最终剩下的点就是集合的个数,每个集合只会留下一个点。所以移除的点就是点的总数减去集合的个数 `len(stones) - uf.totalCount()`
48+
- 如果暴力合并集合,时间复杂度也非常差,可以由优化的地方。再遍历所有点的过程中,可以把遍历过的行和列存起来。这里可以用 map 来记录,key 为行号,value 为上一次遍历过的点的序号。同样,列也可以用 map 存起来,key 为列号,value 为上一次遍历过的点的序号。经过这样的优化以后,时间复杂度会提高不少。
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
# [959. Regions Cut By Slashes](https://leetcode.com/problems/regions-cut-by-slashes/)
2+
3+
4+
## 题目:
5+
6+
In a N x N `grid` composed of 1 x 1 squares, each 1 x 1 square consists of a `/``\`, or blank space. These characters divide the square into contiguous regions.
7+
8+
(Note that backslash characters are escaped, so a `\` is represented as `"\\"`.)
9+
10+
Return the number of regions.
11+
12+
**Example 1:**
13+
14+
Input:
15+
[
16+
" /",
17+
"/ "
18+
]
19+
Output: 2
20+
Explanation: The 2x2 grid is as follows:
21+
22+
![](https://assets.leetcode-cn.com/aliyun-lc-upload/uploads/2018/12/15/1.png)
23+
24+
**Example 2:**
25+
26+
Input:
27+
[
28+
" /",
29+
" "
30+
]
31+
Output: 1
32+
Explanation: The 2x2 grid is as follows:
33+
34+
![](https://assets.leetcode-cn.com/aliyun-lc-upload/uploads/2018/12/15/2.png)
35+
36+
**Example 3:**
37+
38+
Input:
39+
[
40+
"\\/",
41+
"/\\"
42+
]
43+
Output: 4
44+
Explanation: (Recall that because \ characters are escaped, "\\/" refers to \/, and "/\\" refers to /\.)
45+
The 2x2 grid is as follows:
46+
47+
![](https://assets.leetcode-cn.com/aliyun-lc-upload/uploads/2018/12/15/3.png)
48+
49+
**Example 4:**
50+
51+
Input:
52+
[
53+
"/\\",
54+
"\\/"
55+
]
56+
Output: 5
57+
Explanation: (Recall that because \ characters are escaped, "/\\" refers to /\, and "\\/" refers to \/.)
58+
The 2x2 grid is as follows:
59+
60+
![](https://assets.leetcode-cn.com/aliyun-lc-upload/uploads/2018/12/15/4.png)
61+
62+
**Example 5:**
63+
64+
Input:
65+
[
66+
"//",
67+
"/ "
68+
]
69+
Output: 3
70+
Explanation: The 2x2 grid is as follows:
71+
72+
![](https://assets.leetcode-cn.com/aliyun-lc-upload/uploads/2018/12/15/5.png)
73+
74+
**Note:**
75+
76+
1. `1 <= grid.length == grid[0].length <= 30`
77+
2. `grid[i][j]` is either `'/'``'\'`, or `' '`.
78+
79+
80+
## 题目大意
81+
82+
在由 1 x 1 方格组成的 N x N 网格 grid 中,每个 1 x 1 方块由 /、\ 或空格构成。这些字符会将方块划分为一些共边的区域。(请注意,反斜杠字符是转义的,因此 \ 用 "\\" 表示)返回区域的数目。
83+
84+
85+
提示:
86+
87+
- 1 <= grid.length == grid[0].length <= 30
88+
- grid[i][j] 是 '/'、'\'、或 ' '。
89+
90+
## 解题思路
91+
92+
93+
- 给出一个字符串,代表的是 `N x N` 正方形中切分的情况,有 2 种切分的情况 `'\'``'/'` ,即从左上往右下切和从右上往左下切。问按照给出的切分方法,能把 `N x N` 正方形切成几部分?
94+
- 这一题解题思路是并查集。先将每个 `1*1` 的正方形切分成下图的样子。分成 4 小块。然后按照题目给的切分图来合并各个小块。
95+
96+
![](https://img.halfrost.com/Leetcode/leetcode_959.png)
97+
98+
- 遇到 `'\\'`,就把第 0 块和第 1 块 `union()` 起来,第 2 块和第 3 块 `union()` 起来;遇到 `'/'`,就把第 0 块和第 3 块 `union()` 起来,第 2 块和第 1 块 `union()` 起来;遇到 `' '`,就把第 0 块和第 1 块 `union()` 起来,第 2 块和第 1 块 `union()` 起来,第 2 块和第 3 块 `union()` 起来,即 4 块都 `union()` 起来;最后还需要记得上一行和下一行还需要 `union()`,即本行的第 2 块和下一行的第 0 块 `union()` 起来;左边一列和右边一列也需要 `union()`。即本列的第 1 块和右边一列的第 3 块 `union()` 起来。最后计算出集合总个数就是最终答案了。

0 commit comments

Comments
 (0)