diff --git a/Contents/00.Introduction/04.Solutions-List.md b/Contents/00.Introduction/04.Solutions-List.md index 938051cc..d56865d3 100644 --- a/Contents/00.Introduction/04.Solutions-List.md +++ b/Contents/00.Introduction/04.Solutions-List.md @@ -1,4 +1,4 @@ -# LeetCode 题解(已完成 850 道) +# LeetCode 题解(已完成 856 道) | 题号 | 标题 | 题解 | 标签 | 难度 | | :------ | :------ | :------ | :------ | :------ | @@ -512,6 +512,7 @@ | 1037 | [有效的回旋镖](https://leetcode.cn/problems/valid-boomerang/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/1037.%20%E6%9C%89%E6%95%88%E7%9A%84%E5%9B%9E%E6%97%8B%E9%95%96.md) | 几何、数组、数学 | 简单 | | 1038 | [从二叉搜索树到更大和树](https://leetcode.cn/problems/binary-search-tree-to-greater-sum-tree/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/1038.%20%E4%BB%8E%E4%BA%8C%E5%8F%89%E6%90%9C%E7%B4%A2%E6%A0%91%E5%88%B0%E6%9B%B4%E5%A4%A7%E5%92%8C%E6%A0%91.md) | 树、深度优先搜索、二叉搜索树、二叉树 | 中等 | | 1039 | [多边形三角剖分的最低得分](https://leetcode.cn/problems/minimum-score-triangulation-of-polygon/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/1039.%20%E5%A4%9A%E8%BE%B9%E5%BD%A2%E4%B8%89%E8%A7%92%E5%89%96%E5%88%86%E7%9A%84%E6%9C%80%E4%BD%8E%E5%BE%97%E5%88%86.md) | 数组、动态规划 | 中等 | +| 1041 | [困于环中的机器人](https://leetcode.cn/problems/robot-bounded-in-circle/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/1041.%20%E5%9B%B0%E4%BA%8E%E7%8E%AF%E4%B8%AD%E7%9A%84%E6%9C%BA%E5%99%A8%E4%BA%BA.md) | 数学、字符串、模拟 | 中等 | | 1047 | [删除字符串中的所有相邻重复项](https://leetcode.cn/problems/remove-all-adjacent-duplicates-in-string/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/1047.%20%E5%88%A0%E9%99%A4%E5%AD%97%E7%AC%A6%E4%B8%B2%E4%B8%AD%E7%9A%84%E6%89%80%E6%9C%89%E7%9B%B8%E9%82%BB%E9%87%8D%E5%A4%8D%E9%A1%B9.md) | 栈、字符串 | 简单 | | 1049 | [最后一块石头的重量 II](https://leetcode.cn/problems/last-stone-weight-ii/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/1049.%20%E6%9C%80%E5%90%8E%E4%B8%80%E5%9D%97%E7%9F%B3%E5%A4%B4%E7%9A%84%E9%87%8D%E9%87%8F%20II.md) | 数组、动态规划 | 中等 | | 1051 | [高度检查器](https://leetcode.cn/problems/height-checker/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/1051.%20%E9%AB%98%E5%BA%A6%E6%A3%80%E6%9F%A5%E5%99%A8.md) | 数组、计数排序、排序 | 简单 | @@ -527,6 +528,7 @@ | 1103 | [分糖果 II](https://leetcode.cn/problems/distribute-candies-to-people/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/1103.%20%E5%88%86%E7%B3%96%E6%9E%9C%20II.md) | 数学、模拟 | 简单 | | 1108 | [IP 地址无效化](https://leetcode.cn/problems/defanging-an-ip-address/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/1108.%20IP%20%E5%9C%B0%E5%9D%80%E6%97%A0%E6%95%88%E5%8C%96.md) | 字符串 | 简单 | | 1109 | [航班预订统计](https://leetcode.cn/problems/corporate-flight-bookings/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/1109.%20%E8%88%AA%E7%8F%AD%E9%A2%84%E8%AE%A2%E7%BB%9F%E8%AE%A1.md) | 数组、前缀和 | 中等 | +| 1110 | [删点成林](https://leetcode.cn/problems/delete-nodes-and-return-forest/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/1110.%20%E5%88%A0%E7%82%B9%E6%88%90%E6%9E%97.md) | 树、深度优先搜索、数组、哈希表、二叉树 | 中等 | | 1122 | [数组的相对排序](https://leetcode.cn/problems/relative-sort-array/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/1122.%20%E6%95%B0%E7%BB%84%E7%9A%84%E7%9B%B8%E5%AF%B9%E6%8E%92%E5%BA%8F.md) | 数组、哈希表、计数排序、排序 | 简单 | | 1136 | [并行课程](https://leetcode.cn/problems/parallel-courses/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/1136.%20%E5%B9%B6%E8%A1%8C%E8%AF%BE%E7%A8%8B.md) | 图、拓扑排序 | 中等 | | 1137 | [第 N 个泰波那契数](https://leetcode.cn/problems/n-th-tribonacci-number/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/1137.%20%E7%AC%AC%20N%20%E4%B8%AA%E6%B3%B0%E6%B3%A2%E9%82%A3%E5%A5%91%E6%95%B0.md) | 记忆化搜索、数学、动态规划 | 简单 | @@ -582,6 +584,7 @@ | 1486 | [数组异或操作](https://leetcode.cn/problems/xor-operation-in-an-array/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/1486.%20%E6%95%B0%E7%BB%84%E5%BC%82%E6%88%96%E6%93%8D%E4%BD%9C.md) | 位运算、数学 | 简单 | | 1491 | [去掉最低工资和最高工资后的工资平均值](https://leetcode.cn/problems/average-salary-excluding-the-minimum-and-maximum-salary/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/1491.%20%E5%8E%BB%E6%8E%89%E6%9C%80%E4%BD%8E%E5%B7%A5%E8%B5%84%E5%92%8C%E6%9C%80%E9%AB%98%E5%B7%A5%E8%B5%84%E5%90%8E%E7%9A%84%E5%B7%A5%E8%B5%84%E5%B9%B3%E5%9D%87%E5%80%BC.md) | 数组、排序 | 简单 | | 1493 | [删掉一个元素以后全为 1 的最长子数组](https://leetcode.cn/problems/longest-subarray-of-1s-after-deleting-one-element/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/1493.%20%E5%88%A0%E6%8E%89%E4%B8%80%E4%B8%AA%E5%85%83%E7%B4%A0%E4%BB%A5%E5%90%8E%E5%85%A8%E4%B8%BA%201%20%E7%9A%84%E6%9C%80%E9%95%BF%E5%AD%90%E6%95%B0%E7%BB%84.md) | 数组、动态规划、滑动窗口 | 中等 | +| 1496 | [判断路径是否相交](https://leetcode.cn/problems/path-crossing/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/1496.%20%E5%88%A4%E6%96%AD%E8%B7%AF%E5%BE%84%E6%98%AF%E5%90%A6%E7%9B%B8%E4%BA%A4.md) | 哈希表、字符串 | 简单 | | 1502 | [判断能否形成等差数列](https://leetcode.cn/problems/can-make-arithmetic-progression-from-sequence/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/1502.%20%E5%88%A4%E6%96%AD%E8%83%BD%E5%90%A6%E5%BD%A2%E6%88%90%E7%AD%89%E5%B7%AE%E6%95%B0%E5%88%97.md) | 数组、排序 | 简单 | | 1507 | [转变日期格式](https://leetcode.cn/problems/reformat-date/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/1507.%20%E8%BD%AC%E5%8F%98%E6%97%A5%E6%9C%9F%E6%A0%BC%E5%BC%8F.md) | 字符串 | 简单 | | 1523 | [在区间范围内统计奇数数目](https://leetcode.cn/problems/count-odd-numbers-in-an-interval-range/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/1523.%20%E5%9C%A8%E5%8C%BA%E9%97%B4%E8%8C%83%E5%9B%B4%E5%86%85%E7%BB%9F%E8%AE%A1%E5%A5%87%E6%95%B0%E6%95%B0%E7%9B%AE.md) | 数学 | 简单 | @@ -599,7 +602,9 @@ | 1614 | [括号的最大嵌套深度](https://leetcode.cn/problems/maximum-nesting-depth-of-the-parentheses/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/1614.%20%E6%8B%AC%E5%8F%B7%E7%9A%84%E6%9C%80%E5%A4%A7%E5%B5%8C%E5%A5%97%E6%B7%B1%E5%BA%A6.md) | 栈、字符串 | 简单 | | 1617 | [统计子树中城市之间最大距离](https://leetcode.cn/problems/count-subtrees-with-max-distance-between-cities/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/1617.%20%E7%BB%9F%E8%AE%A1%E5%AD%90%E6%A0%91%E4%B8%AD%E5%9F%8E%E5%B8%82%E4%B9%8B%E9%97%B4%E6%9C%80%E5%A4%A7%E8%B7%9D%E7%A6%BB.md) | 位运算、树、动态规划、状态压缩、枚举 | 困难 | | 1631 | [最小体力消耗路径](https://leetcode.cn/problems/path-with-minimum-effort/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/1631.%20%E6%9C%80%E5%B0%8F%E4%BD%93%E5%8A%9B%E6%B6%88%E8%80%97%E8%B7%AF%E5%BE%84.md) | 深度优先搜索、广度优先搜索、并查集、数组、二分查找、矩阵、堆(优先队列) | 中等 | +| 1641 | [统计字典序元音字符串的数目](https://leetcode.cn/problems/count-sorted-vowel-strings/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/1641.%20%E7%BB%9F%E8%AE%A1%E5%AD%97%E5%85%B8%E5%BA%8F%E5%85%83%E9%9F%B3%E5%AD%97%E7%AC%A6%E4%B8%B2%E7%9A%84%E6%95%B0%E7%9B%AE.md) | 数学、动态规划、组合数学 | 中等 | | 1646 | [获取生成数组中的最大值](https://leetcode.cn/problems/get-maximum-in-generated-array/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/1646.%20%E8%8E%B7%E5%8F%96%E7%94%9F%E6%88%90%E6%95%B0%E7%BB%84%E4%B8%AD%E7%9A%84%E6%9C%80%E5%A4%A7%E5%80%BC.md) | 数组、动态规划、模拟 | 简单 | +| 1647 | [字符频次唯一的最小删除次数](https://leetcode.cn/problems/minimum-deletions-to-make-character-frequencies-unique/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/1647.%20%E5%AD%97%E7%AC%A6%E9%A2%91%E6%AC%A1%E5%94%AF%E4%B8%80%E7%9A%84%E6%9C%80%E5%B0%8F%E5%88%A0%E9%99%A4%E6%AC%A1%E6%95%B0.md) | 贪心、哈希表、字符串、排序 | 中等 | | 1657 | [确定两个字符串是否接近](https://leetcode.cn/problems/determine-if-two-strings-are-close/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/1657.%20%E7%A1%AE%E5%AE%9A%E4%B8%A4%E4%B8%AA%E5%AD%97%E7%AC%A6%E4%B8%B2%E6%98%AF%E5%90%A6%E6%8E%A5%E8%BF%91.md) | 哈希表、字符串、排序 | 中等 | | 1658 | [将 x 减到 0 的最小操作数](https://leetcode.cn/problems/minimum-operations-to-reduce-x-to-zero/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/1658.%20%E5%B0%86%20x%20%E5%87%8F%E5%88%B0%200%20%E7%9A%84%E6%9C%80%E5%B0%8F%E6%93%8D%E4%BD%9C%E6%95%B0.md) | 数组、哈希表、二分查找、前缀和、滑动窗口 | 中等 | | 1672 | [最富有客户的资产总量](https://leetcode.cn/problems/richest-customer-wealth/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/1672.%20%E6%9C%80%E5%AF%8C%E6%9C%89%E5%AE%A2%E6%88%B7%E7%9A%84%E8%B5%84%E4%BA%A7%E6%80%BB%E9%87%8F.md) | 数组、矩阵 | 简单 | @@ -612,6 +617,7 @@ | 1736 | [替换隐藏数字得到的最晚时间](https://leetcode.cn/problems/latest-time-by-replacing-hidden-digits/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/1736.%20%E6%9B%BF%E6%8D%A2%E9%9A%90%E8%97%8F%E6%95%B0%E5%AD%97%E5%BE%97%E5%88%B0%E7%9A%84%E6%9C%80%E6%99%9A%E6%97%B6%E9%97%B4.md) | 贪心、字符串 | 简单 | | 1742 | [盒子中小球的最大数量](https://leetcode.cn/problems/maximum-number-of-balls-in-a-box/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/1742.%20%E7%9B%92%E5%AD%90%E4%B8%AD%E5%B0%8F%E7%90%83%E7%9A%84%E6%9C%80%E5%A4%A7%E6%95%B0%E9%87%8F.md) | 哈希表、数学、计数 | 简单 | | 1749 | [任意子数组和的绝对值的最大值](https://leetcode.cn/problems/maximum-absolute-sum-of-any-subarray/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/1749.%20%E4%BB%BB%E6%84%8F%E5%AD%90%E6%95%B0%E7%BB%84%E5%92%8C%E7%9A%84%E7%BB%9D%E5%AF%B9%E5%80%BC%E7%9A%84%E6%9C%80%E5%A4%A7%E5%80%BC.md) | 数组、动态规划 | 中等 | +| 1763 | [最长的美好子字符串](https://leetcode.cn/problems/longest-nice-substring/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/1763.%20%E6%9C%80%E9%95%BF%E7%9A%84%E7%BE%8E%E5%A5%BD%E5%AD%90%E5%AD%97%E7%AC%A6%E4%B8%B2.md) | 位运算、哈希表、字符串、分治、滑动窗口 | 简单 | | 1779 | [找到最近的有相同 X 或 Y 坐标的点](https://leetcode.cn/problems/find-nearest-point-that-has-the-same-x-or-y-coordinate/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/1779.%20%E6%89%BE%E5%88%B0%E6%9C%80%E8%BF%91%E7%9A%84%E6%9C%89%E7%9B%B8%E5%90%8C%20X%20%E6%88%96%20Y%20%E5%9D%90%E6%A0%87%E7%9A%84%E7%82%B9.md) | 数组 | 简单 | | 1790 | [仅执行一次字符串交换能否使两个字符串相等](https://leetcode.cn/problems/check-if-one-string-swap-can-make-strings-equal/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/1790.%20%E4%BB%85%E6%89%A7%E8%A1%8C%E4%B8%80%E6%AC%A1%E5%AD%97%E7%AC%A6%E4%B8%B2%E4%BA%A4%E6%8D%A2%E8%83%BD%E5%90%A6%E4%BD%BF%E4%B8%A4%E4%B8%AA%E5%AD%97%E7%AC%A6%E4%B8%B2%E7%9B%B8%E7%AD%89.md) | 哈希表、字符串、计数 | 简单 | | 1791 | [找出星型图的中心节点](https://leetcode.cn/problems/find-center-of-star-graph/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/1791.%20%E6%89%BE%E5%87%BA%E6%98%9F%E5%9E%8B%E5%9B%BE%E7%9A%84%E4%B8%AD%E5%BF%83%E8%8A%82%E7%82%B9.md) | 图 | 简单 | diff --git a/README.md b/README.md index 3ee255d0..1ee270f0 100644 --- a/README.md +++ b/README.md @@ -255,4 +255,4 @@ - [动态规划优化题目](./Contents/10.Dynamic-Programming/11.DP-Optimization/04.DP-Optimization-List.md) ## 11. 附加内容 -## [12. LeetCode 题解(已完成 850 道)](./Contents/00.Introduction/04.Solutions-List.md) \ No newline at end of file +## [12. LeetCode 题解(已完成 856 道)](./Contents/00.Introduction/04.Solutions-List.md) \ No newline at end of file diff --git "a/Solutions/1041. \345\233\260\344\272\216\347\216\257\344\270\255\347\232\204\346\234\272\345\231\250\344\272\272.md" "b/Solutions/1041. \345\233\260\344\272\216\347\216\257\344\270\255\347\232\204\346\234\272\345\231\250\344\272\272.md" new file mode 100644 index 00000000..1ab38240 --- /dev/null +++ "b/Solutions/1041. \345\233\260\344\272\216\347\216\257\344\270\255\347\232\204\346\234\272\345\231\250\344\272\272.md" @@ -0,0 +1,106 @@ +# [1041. 困于环中的机器人](https://leetcode.cn/problems/robot-bounded-in-circle/) + +- 标签:数学、字符串、模拟 +- 难度:中等 + +## 题目链接 + +- [1041. 困于环中的机器人 - 力扣](https://leetcode.cn/problems/robot-bounded-in-circle/) + +## 题目大意 + +**描述**:在无限的平面上,机器人最初位于 $(0, 0)$ 处,面朝北方。注意: + +- 北方向 是 $y$ 轴的正方向。 +- 南方向 是 $y$ 轴的负方向。 +- 东方向 是 $x$ 轴的正方向。 +- 西方向 是 $x$ 轴的负方向。 + +机器人可以接受下列三条指令之一: + +- `"G"`:直走 $1$ 个单位 +- `"L"`:左转 $90$ 度 +- `"R"`:右转 $90$ 度 + +给定一个字符串 $instructions$,机器人按顺序执行指令 $instructions$,并一直重复它们。 + +**要求**:只有在平面中存在环使得机器人永远无法离开时,返回 $True$。否则,返回 $False$。 + +**说明**: + +- $1 \le instructions.length \le 100$。 +- $instructions[i]$ 仅包含 `'G'`,`'L'`,`'R'`。 + +**示例**: + +- 示例 1: + +```python +输入:instructions = "GGLLGG" +输出:True +解释:机器人最初在(0,0)处,面向北方。 +“G”:移动一步。位置:(0,1)方向:北。 +“G”:移动一步。位置:(0,2).方向:北。 +“L”:逆时针旋转90度。位置:(0,2).方向:西。 +“L”:逆时针旋转90度。位置:(0,2)方向:南。 +“G”:移动一步。位置:(0,1)方向:南。 +“G”:移动一步。位置:(0,0)方向:南。 +重复指令,机器人进入循环:(0,0)——>(0,1)——>(0,2)——>(0,1)——>(0,0)。 +在此基础上,我们返回 True。 +``` + +- 示例 2: + +```python +输入:instructions = "GG" +输出:False +解释:机器人最初在(0,0)处,面向北方。 +“G”:移动一步。位置:(0,1)方向:北。 +“G”:移动一步。位置:(0,2).方向:北。 +重复这些指示,继续朝北前进,不会进入循环。 +在此基础上,返回 False。 +``` + +## 解题思路 + +### 思路 1:模拟 + +设定初始位置为 $(0, 0)$,初始方向 $direction = 0$,假设按照给定字符串 $instructions$ 执行一遍之后,位于 $(x, y)$ 处,且方向为 $direction$,则可能出现的所有情况为: + +1. 方向不变($direction == 0$),且 $(x, y) == (0, 0)$,则会一直在原点,无法走出去。 +2. 方向不变($direction == 0$),且 $(x, y) \ne (0, 0)$,则可以走出去。 +3. 方向相反($direction == 2$),无论是否产生位移,则再执行 $1$ 遍将会回到原点。 +4. 方向逆时针 / 顺时针改变 $90°$($direction == 1 \text{ or } 3$),无论是否产生位移,则再执行 $3$ 遍将会回到原点。 + +综上所述,最多模拟 $4$ 次即可知道能否回到原点。 + +从上面也可以等出结论:如果不产生位移,则一定会回到原点。如果改变方向,同样一定会回到原点。 + +我们只需要根据以上结论,按照 $instructions$ 执行一遍之后,通过判断是否产生位移和改变方向,即可判断是否一定会回到原点。 + +### 思路 1:代码 + +```Python +class Solution: + def isRobotBounded(self, instructions: str) -> bool: + # 分别代表北、东、南、西 + directions = [(0, 1), (-1, 0), (0, -1), (1, 0)] + x, y = 0, 0 + # 初始方向为北 + direction = 0 + for step in instructions: + if step == 'G': + x += directions[direction][0] + y += directions[direction][1] + elif step == 'L': + direction = (direction + 1) % 4 + else: + direction = (direction + 3) % 4 + + return (x == 0 and y == 0) or direction != 0 +``` + +### 思路 1:复杂度分析 + +- **时间复杂度**:$O(n)$,其中 $n$ 为字符串 $instructions$ 的长度。 +- **空间复杂度**:$O(1)$。 diff --git "a/Solutions/1110. \345\210\240\347\202\271\346\210\220\346\236\227.md" "b/Solutions/1110. \345\210\240\347\202\271\346\210\220\346\236\227.md" new file mode 100644 index 00000000..de2d2f16 --- /dev/null +++ "b/Solutions/1110. \345\210\240\347\202\271\346\210\220\346\236\227.md" @@ -0,0 +1,98 @@ +# [1110. 删点成林](https://leetcode.cn/problems/delete-nodes-and-return-forest/) + +- 标签:树、深度优先搜索、数组、哈希表、二叉树 +- 难度:中等 + +## 题目链接 + +- [1110. 删点成林 - 力扣](https://leetcode.cn/problems/delete-nodes-and-return-forest/) + +## 题目大意 + +**描述**:给定二叉树的根节点 $root$,树上每个节点都有一个不同的值。 + +如果节点值在 $to\underline{}delete$ 中出现,我们就把该节点从树上删去,最后得到一个森林(一些不相交的树构成的集合)。 + +**要求**:返回森林中的每棵树。你可以按任意顺序组织答案。 + +**说明**: + +- 树中的节点数最大为 $1000$。 +- 每个节点都有一个介于 $1$ 到 $1000$ 之间的值,且各不相同。 +- $to\underline{}delete.length \le 1000$。 +- $to\underline{}delete$ 包含一些从 $1$ 到 $1000$、各不相同的值。 + +**示例**: + +- 示例 1: + +![](https://assets.leetcode-cn.com/aliyun-lc-upload/uploads/2019/07/05/screen-shot-2019-07-01-at-53836-pm.png) + +```python +输入:root = [1,2,3,4,5,6,7], to_delete = [3,5] +输出:[[1,2,null,4],[6],[7]] +``` + +- 示例 2: + +```python +输入:root = [1,2,4,null,3], to_delete = [3] +输出:[[1,2,4]] +``` + +## 解题思路 + +### 思路 1:深度优先搜索 + +将待删除节点数组 $to\underline{}delete$ 转为集合 $deletes$,则每次能以 $O(1)$ 的时间复杂度判断节点值是否在待删除节点数组中。 + +如果当前节点值在待删除节点数组中,则删除当前节点后,我们还需要判断其左右子节点是否也在待删除节点数组中。 + +以此类推,还需要判断左右子节点的左右子节点。。。 + +因此,我们应该递归遍历处理完所有的左右子树,再判断当前节点的左右子节点是否在待删除节点数组中。如果在,则将其加入到答案数组中。 + +为此我们可以写一个深度优先搜索算法,具体步骤如下: + +1. 如果当前根节点为空,则返回 `None`。 +2. 递归遍历处理完当前根节点的左右子树,更新当前节点的左右子树(子节点被删除的情况下需要更新当前根节点的左右子树)。 +3. 如果当前根节点值在待删除节点数组中: + 1. 如果当前根节点的左子树没有在被删除节点数组中,将左子树节点加入到答案数组中。 + 2. 如果当前根节点的右子树没有在被删除节点数组中,将右子树节点加入到答案数组中。 + 3. 返回 `None`,表示当前节点被删除。 +4. 如果当前根节点值不在待删除节点数组中: + 1. 返回根节点,表示当前节点没有被删除。 + +### 思路 1:代码 + +```Python +class Solution: + def delNodes(self, root: Optional[TreeNode], to_delete: List[int]) -> List[TreeNode]: + forest = [] + deletes = set(to_delete) + def dfs(root): + if not root: + return None + root.left = dfs(root.left) + root.right = dfs(root.right) + + if root.val in deletes: + if root.left: + forest.append(root.left) + if root.right: + forest.append(root.right) + return None + else: + return root + + + if dfs(root): + forest.append(root) + return forest +``` + +### 思路 1:复杂度分析 + +- **时间复杂度**:$O(n)$,其中 $n$ 为二叉树中节点个数。 +- **空间复杂度**:$O(n)$。 + diff --git "a/Solutions/1496. \345\210\244\346\226\255\350\267\257\345\276\204\346\230\257\345\220\246\347\233\270\344\272\244.md" "b/Solutions/1496. \345\210\244\346\226\255\350\267\257\345\276\204\346\230\257\345\220\246\347\233\270\344\272\244.md" new file mode 100644 index 00000000..0850e901 --- /dev/null +++ "b/Solutions/1496. \345\210\244\346\226\255\350\267\257\345\276\204\346\230\257\345\220\246\347\233\270\344\272\244.md" @@ -0,0 +1,86 @@ +# [1496. 判断路径是否相交](https://leetcode.cn/problems/path-crossing/) + +- 标签:哈希表、字符串 +- 难度:简单 + +## 题目链接 + +- [1496. 判断路径是否相交 - 力扣](https://leetcode.cn/problems/path-crossing/) + +## 题目大意 + +**描述**:给定一个字符串 $path$,其中 $path[i]$ 的值可以是 `'N'`、`'S'`、`'E'` 或者 `'W'`,分别表示向北、向南、向东、向西移动一个单位。 + +你从二维平面上的原点 $(0, 0)$ 处开始出发,按 $path$ 所指示的路径行走。 + +**要求**:如果路径在任何位置上与自身相交,也就是走到之前已经走过的位置,请返回 $True$;否则,返回 $False$。 + +**说明**: + +- $1 \le path.length \le 10^4$。 +- $path[i]$ 为 `'N'`、`'S'`、`'E'` 或 `'W'`。 + +**示例**: + +- 示例 1: + +![](https://assets.leetcode-cn.com/aliyun-lc-upload/uploads/2020/06/28/screen-shot-2020-06-10-at-123929-pm.png) + +```python +输入:path = "NES" +输出:false +解释:该路径没有在任何位置相交。 +``` + +- 示例 2: + +![](https://assets.leetcode-cn.com/aliyun-lc-upload/uploads/2020/06/28/screen-shot-2020-06-10-at-123843-pm.png) + +```python +输入:path = "NESWW" +输出:true +解释:该路径经过原点两次。 +``` + +## 解题思路 + +### 思路 1:哈希表 + 模拟 + +1. 使用哈希表将 `'N'`、`'S'`、`'E'`、`'W'` 对应横纵坐标轴上的改变表示出来。 +2. 使用集合 $visited$ 存储走过的坐标元组。 +3. 遍历 $path$,按照 $path$ 所指示的路径模拟行走,并将所走过的坐标使用 $visited$ 存储起来。 +4. 如果在 $visited$ 遇到已经走过的坐标,则返回 $True$。 +5. 如果遍历完仍未发现已经走过的坐标,则返回 $False$。 + +### 思路 1:代码 + +```Python +class Solution: + def isPathCrossing(self, path: str) -> bool: + directions = { + "N" : (-1, 0), + "S" : (1, 0), + "W" : (0, -1), + "E" : (0, 1), + } + + x, y = 0, 0 + + visited = set() + visited.add((x, y)) + + for ch in path: + x += directions[ch][0] + y += directions[ch][1] + if (x, y) in visited: + return True + visited.add((x, y)) + + return False +``` + +### 思路 1:复杂度分析 + +- **时间复杂度**:$O(n)$,其中 $n$ 为数组 $path$ 的长度。 +- **空间复杂度**:$O(n)$。 + diff --git "a/Solutions/1641. \347\273\237\350\256\241\345\255\227\345\205\270\345\272\217\345\205\203\351\237\263\345\255\227\347\254\246\344\270\262\347\232\204\346\225\260\347\233\256.md" "b/Solutions/1641. \347\273\237\350\256\241\345\255\227\345\205\270\345\272\217\345\205\203\351\237\263\345\255\227\347\254\246\344\270\262\347\232\204\346\225\260\347\233\256.md" new file mode 100644 index 00000000..f3c8abe3 --- /dev/null +++ "b/Solutions/1641. \347\273\237\350\256\241\345\255\227\345\205\270\345\272\217\345\205\203\351\237\263\345\255\227\347\254\246\344\270\262\347\232\204\346\225\260\347\233\256.md" @@ -0,0 +1,67 @@ +# [1641. 统计字典序元音字符串的数目](https://leetcode.cn/problems/count-sorted-vowel-strings/) + +- 标签:数学、动态规划、组合数学 +- 难度:中等 + +## 题目链接 + +- [1641. 统计字典序元音字符串的数目 - 力扣](https://leetcode.cn/problems/count-sorted-vowel-strings/) + +## 题目大意 + +**描述**:给定一个整数 $n$。 + +**要求**:返回长度为 $n$、仅由原音($a$、$e$、$i$、$o$、$u$)组成且按字典序排序的字符串数量。 + +**说明**: + +- 字符串 $a$ 按字典序排列需要满足:对于所有有效的 $i$,$s[i]$ 在字母表中的位置总是与 $s[i + 1]$ 相同或在 $s[i+1] $之前。 +- $1 \le n \le 50$。 + +**示例**: + +- 示例 1: + +```python +输入:n = 1 +输出:5 +解释:仅由元音组成的 5 个字典序字符串为 ["a","e","i","o","u"] +``` + +- 示例 2: + +```python +输入:n = 2 +输出:15 +解释:仅由元音组成的 15 个字典序字符串为 +["aa","ae","ai","ao","au","ee","ei","eo","eu","ii","io","iu","oo","ou","uu"] +注意,"ea" 不是符合题意的字符串,因为 'e' 在字母表中的位置比 'a' 靠后 +``` + +## 解题思路 + +### 思路 1:组和数学 + +题目要求按照字典序排列,则如果确定了每个元音的出现次数可以确定一个序列。 + +对于长度为 $n$ 的序列,$a$、$e$、$i$、$o$、$u$ 出现次数加起来为 $n$ 次,且顺序为 $a…a \rightarrow e…e \rightarrow i…i \rightarrow o…o \rightarrow u…u$。 + +我们可以看作是将 $n$ 分隔成了 $5$ 份,每一份对应一个原音字母的数量。 + +我们可以使用「隔板法」的方式,看作有 $n$ 个球,$4$ 个板子,将 $n$ 个球分隔成 $5$ 份。 + +则一共有 $n + 4$ 个位置可以放板子,总共需要放 $4$ 个板子,则答案为 $C_{n + 4}^4$,其中 $C$ 为组和数。 + +### 思路 1:代码 + +```Python +class Solution: + def countVowelStrings(self, n: int) -> int: + return comb(n + 4, 4) +``` + +### 思路 1:复杂度分析 + +- **时间复杂度**:$O(| \sum |)$,其中 $\sum$ 为字符集,本题中 $| \sum | = 5$ 。 +- **空间复杂度**:$O(1)$。 + diff --git "a/Solutions/1647. \345\255\227\347\254\246\351\242\221\346\254\241\345\224\257\344\270\200\347\232\204\346\234\200\345\260\217\345\210\240\351\231\244\346\254\241\346\225\260.md" "b/Solutions/1647. \345\255\227\347\254\246\351\242\221\346\254\241\345\224\257\344\270\200\347\232\204\346\234\200\345\260\217\345\210\240\351\231\244\346\254\241\346\225\260.md" new file mode 100644 index 00000000..b56470ed --- /dev/null +++ "b/Solutions/1647. \345\255\227\347\254\246\351\242\221\346\254\241\345\224\257\344\270\200\347\232\204\346\234\200\345\260\217\345\210\240\351\231\244\346\254\241\346\225\260.md" @@ -0,0 +1,75 @@ +# [1647. 字符频次唯一的最小删除次数](https://leetcode.cn/problems/minimum-deletions-to-make-character-frequencies-unique/) + +- 标签:贪心、哈希表、字符串、排序 +- 难度:中等 + +## 题目链接 + +- [1647. 字符频次唯一的最小删除次数 - 力扣](https://leetcode.cn/problems/minimum-deletions-to-make-character-frequencies-unique/) + +## 题目大意 + +**描述**:给定一个字符串 $s$。 + +**要求**:返回使 $s$ 成为优质字符串需要删除的最小字符数。 + +**说明**: + +- **频次**:指的是该字符在字符串中的出现次数。例如,在字符串 `"aab"` 中,`'a'` 的频次是 $2$,而 `'b'` 的频次是 $1$。 +- **优质字符串**:如果字符串 $s$ 中不存在两个不同字符频次相同的情况,就称 $s$ 是优质字符串。 +- $1 \le s.length \le 10^5$。 +- $s$ 仅含小写英文字母。 + +**示例**: + +- 示例 1: + +```python +输入:s = "aab" +输出:0 +解释:s 已经是优质字符串。 +``` + +- 示例 2: + +```python +输入:s = "aaabbbcc" +输出:2 +解释:可以删除两个 'b' , 得到优质字符串 "aaabcc" 。 +另一种方式是删除一个 'b' 和一个 'c' ,得到优质字符串 "aaabbc"。 +``` + +## 解题思路 + +### 思路 1:贪心算法 + 哈希表 + +1. 使用哈希表 $cnts$ 统计每字符串中每个字符出现次数。 +2. 然后使用集合 $s\underline{}set$ 保存不同的出现次数。 +3. 遍历哈希表中所偶出现次数: + 1. 如果当前出现次数不在集合 $s\underline{}set$ 中,则将该次数添加到集合 $s\underline{}set$ 中。 + 2. 如果当前出现次数在集合 $s\underline{}set$ 中,则不断减少该次数,直到该次数不在集合 $s\underline{}set$ 中停止,将次数添加到集合 $s\underline{}set$ 中,同时将减少次数累加到答案 $ans$ 中。 +4. 遍历完哈希表后返回答案 $ans$。 + +### 思路 1:代码 + +```Python +class Solution: + def minDeletions(self, s: str) -> int: + cnts = Counter(s) + s_set = set() + + ans = 0 + for key, value in cnts.items(): + while value > 0 and value in s_set: + value -= 1 + ans += 1 + s_set.add(value) + + return ans +``` + +### 思路 1:复杂度分析 + +- **时间复杂度**:$O(n)$。 +- **空间复杂度**:$O(n)$。 + diff --git "a/Solutions/1763. \346\234\200\351\225\277\347\232\204\347\276\216\345\245\275\345\255\220\345\255\227\347\254\246\344\270\262.md" "b/Solutions/1763. \346\234\200\351\225\277\347\232\204\347\276\216\345\245\275\345\255\220\345\255\227\347\254\246\344\270\262.md" new file mode 100644 index 00000000..a0c91b95 --- /dev/null +++ "b/Solutions/1763. \346\234\200\351\225\277\347\232\204\347\276\216\345\245\275\345\255\220\345\255\227\347\254\246\344\270\262.md" @@ -0,0 +1,80 @@ +# [1763. 最长的美好子字符串](https://leetcode.cn/problems/longest-nice-substring/) + +- 标签:位运算、哈希表、字符串、分治、滑动窗口 +- 难度:简单 + +## 题目链接 + +- [1763. 最长的美好子字符串 - 力扣](https://leetcode.cn/problems/longest-nice-substring/) + +## 题目大意 + +**描述**: 给定一个字符串 $s$。 + +**要求**:返回 $s$ 最长的美好子字符串。 + +**说明**: + +- **美好字符串**:当一个字符串 $s$ 包含的每一种字母的大写和小写形式同时出现在 $s$ 中,就称这个字符串 $s$ 是美好字符串。 +- $1 \le s.length \le 100$。 + +**示例**: + +- 示例 1: + +```python +输入:s = "YazaAay" +输出:"aAa" +解释:"aAa" 是一个美好字符串,因为这个子串中仅含一种字母,其小写形式 'a' 和大写形式 'A' 也同时出现了。 +"aAa" 是最长的美好子字符串。 +``` + +- 示例 2: + +```python +输入:s = "Bb" +输出:"Bb" +解释:"Bb" 是美好字符串,因为 'B' 和 'b' 都出现了。整个字符串也是原字符串的子字符串。 +``` + +## 解题思路 + +### 思路 1:枚举 + +字符串 $s$ 的范围为 $[1, 100]$,长度较小,我们可以枚举所有的子串,判断该子串是否为美好字符串。 + +由于大小写英文字母各有 $26$ 位,则我们可以利用二进制来标记某字符是否在子串中出现过,我们使用 $lower$ 标记子串中出现过的小写字母,使用 $upper$ 标记子串中出现过的大写字母。如果满足 $lower == upper$,则说明该子串为美好字符串。 + +具体解法步骤如下: + +1. 使用二重循环遍历字符串。对于子串 $s[i]…s[j]$,使用 $lower$ 标记子串中出现过的小写字母,使用 $upper$ 标记子串中出现过的大写字母。 +2. 如果 $s[j]$ 为小写字母,则 $lower$ 对应位置标记为出现过该小写字母,即:`lower |= 1 << (ord(s[j]) - ord('a'))`。 +3. 如果 $s[j]$ 为大写字母,则 $upper$ 对应位置标记为出现过该小写字母,即:`upper |= 1 << (ord(s[j]) - ord('A'))`。 +4. 判断当前子串对应 $lower$ 和 $upper$ 是否相等,如果相等,并且子串长度大于记录的最长美好字符串长度,则更新最长美好字符串长度。 +5. 遍历完返回记录的最长美好字符串长度。 + +### 思路 1:代码 + +```Python +class Solution: + def longestNiceSubstring(self, s: str) -> str: + size = len(s) + max_pos, max_len = 0, 0 + for i in range(size): + lower, upper = 0, 0 + for j in range(i, size): + if s[j].islower(): + lower |= 1 << (ord(s[j]) - ord('a')) + else: + upper |= 1 << (ord(s[j]) - ord('A')) + if lower == upper and j - i + 1 > max_len: + max_len = j - i + 1 + max_pos = i + return s[max_pos: max_pos + max_len] +``` + +### 思路 1:复杂度分析 + +- **时间复杂度**:$O(n^2)$,其中 $n$ 为字符串 $s$ 的长度。 +- **空间复杂度**:$O(1)$。 +