From 87290f9083ae4bc17cddb76d053a8b71d16191c2 Mon Sep 17 00:00:00 2001 From: AC_Oier Date: Wed, 25 May 2022 18:14:50 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E2=9C=A8feat:=20Add=20467?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...10\344\270\255\347\255\211\357\274\211.md" | 36 +++++++++++++++++-- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git "a/LeetCode/461-470/467. \347\216\257\347\273\225\345\255\227\347\254\246\344\270\262\344\270\255\345\224\257\344\270\200\347\232\204\345\255\220\345\255\227\347\254\246\344\270\262\357\274\210\344\270\255\347\255\211\357\274\211.md" "b/LeetCode/461-470/467. \347\216\257\347\273\225\345\255\227\347\254\246\344\270\262\344\270\255\345\224\257\344\270\200\347\232\204\345\255\220\345\255\227\347\254\246\344\270\262\357\274\210\344\270\255\347\255\211\357\274\211.md" index ac8779c6..7a66c23f 100644 --- "a/LeetCode/461-470/467. \347\216\257\347\273\225\345\255\227\347\254\246\344\270\262\344\270\255\345\224\257\344\270\200\347\232\204\345\255\220\345\255\227\347\254\246\344\270\262\357\274\210\344\270\255\347\255\211\357\274\211.md" +++ "b/LeetCode/461-470/467. \347\216\257\347\273\225\345\255\227\347\254\246\344\270\262\344\270\255\345\224\257\344\270\200\347\232\204\345\255\220\345\255\227\347\254\246\344\270\262\357\274\210\344\270\255\347\255\211\357\274\211.md" @@ -45,8 +45,8 @@ Tag : 「线性 DP」、「树状数组」 ### 线性 DP + 树状数组 + 同字符最大长度计数 -> 早上起来没睡醒,第一反应是用「线性 DP + 树状数组」来做,估了一下时间复杂度没问题就写了。 -该做法可能有一定的思维难度,因此可能不是这道中等题的标准解法。 +> ~~早上起来没睡醒~~ 老了,脑袋不行了,第一反应是用「线性 DP + 树状数组」来做,估了一下时间复杂度没问题就写了。 +该做法有一点点思维难度,因此可能不是这道中等题的标准解法。 **定义 $f[i]$ 为以 $s[i]$ 为结尾的最大有效子串的长度。** @@ -110,7 +110,37 @@ class Solution { } ``` * 时间复杂度:$O(n\log{n})$ -* 空间复杂度:$O(C \times N)$,其中 $C = 26$ 为字符串 `p` 的字符集大小 +* 空间复杂度:$O(C \times n)$,其中 $C = 26$ 为字符串 `p` 的字符集大小 + +--- + +### 线性 DP + +对于相同的结尾字符 $c$ 而言,如果在整个动规过程中的最大长度为 $len$,那么以 $c$ 为结尾字符对答案的贡献为 $len$。 + +基于此,我们只需保留解法一中的 `max` 数组即可,同时利用 $f[i]$ 只依赖于 $f[i - 1]$ 进行更新,因此动规数组也可以使用一个变量来代替。 + +代码: +```Java +class Solution { + public int findSubstringInWraproundString(String _p) { + char[] cs = _p.toCharArray(); + int n = cs.length, ans = 0; + int[] max = new int[26]; + max[cs[0] - 'a']++; + for (int i = 1, j = 1; i < n; i++) { + int c = cs[i] - 'a', p = cs[i - 1] - 'a'; + if ((p == 25 && c == 0) || p + 1 == c) j++; + else j = 1; + max[c] = Math.max(max[c], j); + } + for (int i = 0; i < 26; i++) ans += max[i]; + return ans; + } +} +``` +* 时间复杂度:$O(n)$ +* 空间复杂度:$O(C)$,其中 $C = 26$ 为字符串 `p` 的字符集大小 --- From 5512c1537e01941ad4c92bba0392d555be789ae1 Mon Sep 17 00:00:00 2001 From: AC_Oier Date: Fri, 27 May 2022 10:13:41 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E2=9C=A8feat:=20Add=20699=20&=20=E9=9D=A2?= =?UTF-8?q?=E8=AF=95=E9=A2=98=2017.11?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../\345\217\214\346\214\207\351\222\210.md" | 1 + "Index/\346\250\241\346\213\237.md" | 1 + .../\347\272\277\346\256\265\346\240\221.md" | 1 + ...10\345\233\260\351\232\276\357\274\211.md" | 246 ++++++++++++++++++ ...10\344\270\255\347\255\211\357\274\211.md" | 55 ++++ 5 files changed, 304 insertions(+) create mode 100644 "LeetCode/691-700/699. \346\216\211\350\220\275\347\232\204\346\226\271\345\235\227\357\274\210\345\233\260\351\232\276\357\274\211.md" create mode 100644 "LeetCode/\351\235\242\350\257\225\351\242\230/\351\235\242\350\257\225\351\242\230 17.11. \345\215\225\350\257\215\350\267\235\347\246\273\357\274\210\344\270\255\347\255\211\357\274\211.md" diff --git "a/Index/\345\217\214\346\214\207\351\222\210.md" "b/Index/\345\217\214\346\214\207\351\222\210.md" index f578c23e..23b1d5b0 100644 --- "a/Index/\345\217\214\346\214\207\351\222\210.md" +++ "b/Index/\345\217\214\346\214\207\351\222\210.md" @@ -49,4 +49,5 @@ | [2024. 考试的最大困扰度](https://leetcode-cn.com/problems/maximize-the-confusion-of-an-exam/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/maximize-the-confusion-of-an-exam/solution/by-ac_oier-2rii/) | 中等 | 🤩🤩🤩🤩 | | [2047. 句子中的有效单词数](https://leetcode-cn.com/problems/number-of-valid-words-in-a-sentence/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/number-of-valid-words-in-a-sentence/solution/gong-shui-san-xie-jian-dan-zi-fu-chuan-m-5pcz/) | 简单 | 🤩🤩🤩🤩 | | [面试题 01.05. 一次编辑](https://leetcode.cn/problems/one-away-lcci/) | [LeetCode 题解链接](https://leetcode.cn/problems/one-away-lcci/solution/by-ac_oier-7ml0/) | 中等 | 🤩🤩🤩🤩 | +| [面试题 17.11. 单词距离](https://leetcode.cn/problems/find-closest-lcci/) | [LeetCode 题解链接](https://leetcode.cn/problems/find-closest-lcci/solution/by-ac_oier-0hv9/) | 中等 | 🤩🤩🤩🤩 | diff --git "a/Index/\346\250\241\346\213\237.md" "b/Index/\346\250\241\346\213\237.md" index bb27b6a6..1bb85bbc 100644 --- "a/Index/\346\250\241\346\213\237.md" +++ "b/Index/\346\250\241\346\213\237.md" @@ -158,4 +158,5 @@ | [2069. 模拟行走机器人 II](https://leetcode-cn.com/problems/walking-robot-simulation-ii/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/walking-robot-simulation-ii/solution/by-ac_oier-6zib/) | 中等 | 🤩🤩🤩🤩 | | [面试题 01.05. 一次编辑](https://leetcode.cn/problems/one-away-lcci/) | [LeetCode 题解链接](https://leetcode.cn/problems/one-away-lcci/solution/by-ac_oier-7ml0/) | 中等 | 🤩🤩🤩🤩 | | [面试题 10.02. 变位词组](https://leetcode-cn.com/problems/group-anagrams-lcci/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/group-anagrams-lcci/solution/gong-shui-san-xie-tong-ji-bian-wei-ci-de-0iqe/) | 中等 | 🤩🤩🤩🤩 | +| [面试题 17.11. 单词距离](https://leetcode.cn/problems/find-closest-lcci/) | [LeetCode 题解链接](https://leetcode.cn/problems/find-closest-lcci/solution/by-ac_oier-0hv9/) | 中等 | 🤩🤩🤩🤩 | diff --git "a/Index/\347\272\277\346\256\265\346\240\221.md" "b/Index/\347\272\277\346\256\265\346\240\221.md" index d8a52df5..60ad82e2 100644 --- "a/Index/\347\272\277\346\256\265\346\240\221.md" +++ "b/Index/\347\272\277\346\256\265\346\240\221.md" @@ -2,6 +2,7 @@ | ------------------------------------------------------------ | ------------------------------------------------------------ | ---- | -------- | | [307. 区域和检索 - 数组可修改](https://leetcode-cn.com/problems/range-sum-query-mutable/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/range-sum-query-mutable/solution/by-ac_oier-zmbn/) | 中等 | 🤩🤩🤩🤩🤩 | | [327. 区间和的个数](https://leetcode.cn/problems/count-of-range-sum/) | [LeetCode 题解链接](https://leetcode.cn/problems/count-of-range-sum/solution/by-ac_oier-b36o/) | 困难 | 🤩🤩🤩🤩🤩 | +| [699. 掉落的方块](https://leetcode.cn/problems/falling-squares/) | [LeetCode 题解链接](https://leetcode.cn/problems/falling-squares/solution/by-ac_oier-zpf0/) | 困难 | 🤩🤩🤩🤩 | | [729. 我的日程安排表 I](https://leetcode-cn.com/problems/my-calendar-i/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/my-calendar-i/solution/by-ac_oier-1znx/) | 中等 | 🤩🤩🤩🤩🤩 | | [731. 我的日程安排表 II](https://leetcode-cn.com/problems/my-calendar-ii/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/my-calendar-ii/solution/by-ac_oier-okkc/) | 中等 | 🤩🤩🤩🤩🤩 | | [732. 我的日程安排表 III](https://leetcode-cn.com/problems/my-calendar-iii/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/my-calendar-iii/solution/by-ac_oier-cv31/) | 困难 | 🤩🤩🤩🤩🤩 | diff --git "a/LeetCode/691-700/699. \346\216\211\350\220\275\347\232\204\346\226\271\345\235\227\357\274\210\345\233\260\351\232\276\357\274\211.md" "b/LeetCode/691-700/699. \346\216\211\350\220\275\347\232\204\346\226\271\345\235\227\357\274\210\345\233\260\351\232\276\357\274\211.md" new file mode 100644 index 00000000..4fcfe2fa --- /dev/null +++ "b/LeetCode/691-700/699. \346\216\211\350\220\275\347\232\204\346\226\271\345\235\227\357\274\210\345\233\260\351\232\276\357\274\211.md" @@ -0,0 +1,246 @@ +### 题目描述 + +这是 LeetCode 上的 **[699. 掉落的方块](https://leetcode-cn.com/problems/degree-of-an-array/solution/shu-zu-ji-shu-ha-xi-biao-ji-shu-jie-fa-y-a0mg/)** ,难度为 **困难**。 + +Tag : 「线段树(动态开点)」、「线段树」 + + + +在无限长的数轴(即 `x` 轴)上,我们根据给定的顺序放置对应的正方形方块。 + +第 i 个掉落的方块(`positions[i] = (left, side_length)`)是正方形,其中 `left` 表示该方块最左边的点位置(`positions[i][0]`),`side_length` 表示该方块的边长(`positions[i][1]`)。 + +每个方块的底部边缘平行于数轴(即 `x` 轴),并且从一个比目前所有的落地方块更高的高度掉落而下。在上一个方块结束掉落,并保持静止后,才开始掉落新方块。 + +方块的底边具有非常大的粘性,并将保持固定在它们所接触的任何长度表面上(无论是数轴还是其他方块)。邻接掉落的边不会过早地粘合在一起,因为只有底边才具有粘性。 + +返回一个堆叠高度列表 `ans`。每一个堆叠高度 `ans[i]` 表示在通过 `positions[0], positions[1], ..., positions[i]` 表示的方块掉落结束后,目前所有已经落稳的方块堆叠的最高高度。 + +示例 1: +``` +输入: [[1, 2], [2, 3], [6, 1]] + +输出: [2, 5, 5] + +解释: + +第一个方块 positions[0] = [1, 2] 掉落: +_aa +_aa +------- +方块最大高度为 2 。 + +第二个方块 positions[1] = [2, 3] 掉落: +__aaa +__aaa +__aaa +_aa__ +_aa__ +-------------- +方块最大高度为5。 +大的方块保持在较小的方块的顶部,不论它的重心在哪里,因为方块的底部边缘有非常大的粘性。 + +第三个方块 positions[1] = [6, 1] 掉落: +__aaa +__aaa +__aaa +_aa +_aa___a +-------------- +方块最大高度为5。 + +因此,我们返回结果[2, 5, 5]。 +``` + +示例 2: +``` +输入: [[100, 100], [200, 100]] + +输出: [100, 100] + +解释: 相邻的方块不会过早地卡住,只有它们的底部边缘才能粘在表面上。 +``` + +注意: +* $1 <= positions.length <= 1000$ +* $1 <= positions[i][0] <= 10^8$ +* $1 <= positions[i][1] <= 10^6$ + +--- + +### 基本分析 + +为了方便,我们使用 `ps` 来代指 `positions`。 + +每次从插入操作都附带一次询问,因此询问次数为 $1e3$,左端点的最大值为 $10e8$,边长最大值为 $1e6$,由此可知值域范围大于 $1e8$,但不超过 $1e9$。 + +对于值域范围大,但查询次数有限的区间和问题,不久前曾经总结过 : [求解常见「值域爆炸,查询有限」区间问题的几种方式](https://mp.weixin.qq.com/s?__biz=MzU4NDE3MTEyMA==&mid=2247491187&idx=2&sn=bb2d8b7e89c535914da8107387e951a2),可作为前置 🧀 进行了解。 + +而我的个人习惯,一般要么使用「离散化 + 线段树」,要么使用「线段树(动态开点)」进行求解。 + +本题为「非强制在线」问题,因此可以先对 `ps` 数组进行离散化,将值域映射到较小的空间,然后套用固定占用 $4 \times n$ 空间的线段树求解。 + +但更为灵活(能够同时应对强制在线问题)的求解方式是「线段树(动态开点)」。 + +同时实现动态开点的方式有两种: + +1. 根据操作次数对使用到的最大点数进行预估,并采用数组方式进行实现线段树(解法一); +2. 使用动态指针(解法二); + +方式一在不久之前的每日一题 [933. 最近的请求次数](https://sharingsource.github.io/2022/05/06/933.%20%E6%9C%80%E8%BF%91%E7%9A%84%E8%AF%B7%E6%B1%82%E6%AC%A1%E6%95%B0%EF%BC%88%E7%AE%80%E5%8D%95%EF%BC%89/) 讲过,因此今天把方式二也写一下。 + +具体的,我们将顺序放置方块的操作(假设当前方块的左端点为 $a$,边长为 $len$,则有右端点为 $b = a + len$),分成如下两步进行: + +* 查询当前范围 $[a, b]$ 的最大高度为多少,假设为 $cur$; +* 更新当前范围 $[a, b]$ 的最新高度为 $cur + len$。 + +因此这本质上是一个「区间修改 + 区间查询」的问题,我们需要实现带「懒标记」的线段树,从而确保在进行「区间修改」时复杂度仍为 $O(\log{n})$。 + +> 另外有一个需要注意的细节是:不同方块之间的边缘可以重合,但不会导致方块叠加,因此我们当我们对一个区间 $[a, b]$ 进行操作(查询或插入)时,可以将其调整为 $[a, b - 1]$,从而解决边缘叠加操作高度错误的问题。 + +--- + +### 线段树(动态开点 - 估点) + +估点的基本方式在前置 🧀 [求解常见「值域爆炸,查询有限」区间问题的几种方式](https://mp.weixin.qq.com/s?__biz=MzU4NDE3MTEyMA==&mid=2247491187&idx=2&sn=bb2d8b7e89c535914da8107387e951a2) 详细讲过。 + +简单来说,可以直接估算为 $6 \times m \times \log{n}$ 即可,其中 $m$ 为询问次数(对应本题就是 `ps` 的长度),而 $n$ 为值域大小(对应本题可直接取成 $1e9$);而另外一个比较实用(避免估算)的估点方式可以「尽可能的多开点数」,利用题目给定的空间上界和我们创建的自定义类(结构体)的大小,尽可能的多开(不考虑字节对齐,或者结构体过大的情况,`Java` 的 $128M$ 可以开到 $5 \times 10^6$ 以上)。 + +代码: +```Java +class Solution { + class Node { + // ls 和 rs 分别代表当前区间的左右子节点所在 tr 数组中的下标 + // val 代表当前区间的最大高度,add 为懒标记 + int ls, rs, val, add; + } + int N = (int)1e9, cnt = 0; + Node[] tr = new Node[1000010]; + void update(int u, int lc, int rc, int l, int r, int v) { + if (l <= lc && rc <= r) { + tr[u].val = v; + tr[u].add = v; + return ; + } + pushdown(u); + int mid = lc + rc >> 1; + if (l <= mid) update(tr[u].ls, lc, mid, l, r, v); + if (r > mid) update(tr[u].rs, mid + 1, rc, l, r, v); + pushup(u); + } + int query(int u, int lc, int rc, int l, int r) { + if (l <= lc && rc <= r) return tr[u].val; + pushdown(u); + int mid = lc + rc >> 1, ans = 0; + if (l <= mid) ans = query(tr[u].ls, lc, mid, l, r); + if (r > mid) ans = Math.max(ans, query(tr[u].rs, mid + 1, rc, l, r)); + return ans; + } + void pushdown(int u) { + if (tr[u] == null) tr[u] = new Node(); + if (tr[u].ls == 0) { + tr[u].ls = ++cnt; + tr[tr[u].ls] = new Node(); + } + if (tr[u].rs == 0) { + tr[u].rs = ++cnt; + tr[tr[u].rs] = new Node(); + } + if (tr[u].add == 0) return ; + int add = tr[u].add; + tr[tr[u].ls].add = add; tr[tr[u].rs].add = add; + tr[tr[u].ls].val = add; tr[tr[u].rs].val = add; + tr[u].add = 0; + } + void pushup(int u) { + tr[u].val = Math.max(tr[tr[u].ls].val, tr[tr[u].rs].val); + } + public List fallingSquares(int[][] ps) { + List ans = new ArrayList<>(); + tr[1] = new Node(); + for (int[] info : ps) { + int x = info[0], h = info[1], cur = query(1, 1, N, x, x + h - 1); + update(1, 1, N, x, x + h - 1, cur + h); + ans.add(tr[1].val); + } + return ans; + } +} +``` +* 时间复杂度:令 $m$ 为查询次数,$n$ 为值域大小,复杂度为 $O(m\log{n})$ +* 空间复杂度:$O(m\log{n})$ + +--- + +### 线段树(动态开点 - 动态指针) + +利用「动态指针」实现的「动态开点」可以有效避免数组估点问题,更重要的是可以有效避免 `new` 大数组的初始化开销,对于 LC 这种还跟你算所有样例总时长的 OJ 来说,在不考虑 `static` 优化/全局数组优化 的情况下,动态指针的方式要比估点的方式来得好。 + +代码: +```Java +class Solution { + int N = (int)1e9; + class Node { + // ls 和 rs 分别代表当前区间的左右子节点 + Node ls, rs; + // val 代表当前区间的最大高度,add 为懒标记 + int val, add; + } + Node root = new Node(); + void update(Node node, int lc, int rc, int l, int r, int v) { + if (l <= lc && rc <= r) { + node.add = v; + node.val = v; + return ; + } + pushdown(node); + int mid = lc + rc >> 1; + if (l <= mid) update(node.ls, lc, mid, l, r, v); + if (r > mid) update(node.rs, mid + 1, rc, l, r, v); + pushup(node); + } + int query(Node node, int lc, int rc, int l, int r) { + if (l <= lc && rc <= r) return node.val; + pushdown(node); + int mid = lc + rc >> 1, ans = 0; + if (l <= mid) ans = query(node.ls, lc, mid, l, r); + if (r > mid) ans = Math.max(ans, query(node.rs, mid + 1, rc, l, r)); + return ans; + } + void pushdown(Node node) { + if (node.ls == null) node.ls = new Node(); + if (node.rs == null) node.rs = new Node(); + if (node.add == 0) return ; + node.ls.add = node.add; node.rs.add = node.add; + node.ls.val = node.add; node.rs.val = node.add; + node.add = 0; + } + void pushup(Node node) { + node.val = Math.max(node.ls.val, node.rs.val); + } + public List fallingSquares(int[][] ps) { + List ans = new ArrayList<>(); + for (int[] info : ps) { + int x = info[0], h = info[1], cur = query(root, 0, N, x, x + h - 1); + update(root, 0, N, x, x + h - 1, cur + h); + ans.add(root.val); + } + return ans; + } +} +``` +* 时间复杂度:令 $m$ 为查询次数,$n$ 为值域大小,复杂度为 $O(m\log{n})$ +* 空间复杂度:$O(m\log{n})$ + +--- + +### 最后 + +这是我们「刷穿 LeetCode」系列文章的第 `No.699` 篇,系列开始于 2021/01/01,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先把所有不带锁的题目刷完。 + +在这个系列文章里面,除了讲解解题思路以外,还会尽可能给出最为简洁的代码。如果涉及通解还会相应的代码模板。 + +为了方便各位同学能够电脑上进行调试和提交代码,我建立了相关的仓库:https://github.com/SharingSource/LogicStack-LeetCode 。 + +在仓库地址里,你可以看到系列文章的题解链接、系列文章的相应代码、LeetCode 原题链接和其他优选题解。 + diff --git "a/LeetCode/\351\235\242\350\257\225\351\242\230/\351\235\242\350\257\225\351\242\230 17.11. \345\215\225\350\257\215\350\267\235\347\246\273\357\274\210\344\270\255\347\255\211\357\274\211.md" "b/LeetCode/\351\235\242\350\257\225\351\242\230/\351\235\242\350\257\225\351\242\230 17.11. \345\215\225\350\257\215\350\267\235\347\246\273\357\274\210\344\270\255\347\255\211\357\274\211.md" new file mode 100644 index 00000000..5652e635 --- /dev/null +++ "b/LeetCode/\351\235\242\350\257\225\351\242\230/\351\235\242\350\257\225\351\242\230 17.11. \345\215\225\350\257\215\350\267\235\347\246\273\357\274\210\344\270\255\347\255\211\357\274\211.md" @@ -0,0 +1,55 @@ +### 题目描述 + +这是 LeetCode 上的 **[面试题 17.11. 单词距离](https://leetcode.cn/problems/find-closest-lcci/solution/by-ac_oier-0hv9/)** ,难度为 **中等**。 + +Tag : 「模拟」、「双指针」 + + + +有个内含单词的超大文本文件,给定任意两个不同的单词,找出在这个文件中这两个单词的最短距离(相隔单词数)。如果寻找过程在这个文件中会重复多次,而每次寻找的单词不同,你能对此优化吗? + +示例: +``` +输入:words = ["I","am","a","student","from","a","university","in","a","city"], word1 = "a", word2 = "student" + +输出:1 +``` +提示: +* $words.length <= 100000$ + +--- + +### 模拟 + +对 `words` 进行遍历,使用两个指针 `p` 和 `q` 分别记录最近的两个关键字的位置,并维护更新最小距离。 + +代码: +```Java +class Solution { + public int findClosest(String[] ws, String a, String b) { + int n = ws.length, ans = n; + for (int i = 0, p = -1, q = -1; i < n; i++) { + String t = ws[i]; + if (t.equals(a)) p = i; + if (t.equals(b)) q = i; + if (p != -1 && q != -1) ans = Math.min(ans, Math.abs(p - q)); + } + return ans; + } +} +``` +* 时间复杂度:$O(n)$ +* 空间复杂度:$O(1)$ + +--- + +### 最后 + +这是我们「刷穿 LeetCode」系列文章的第 `No.面试题 17.11` 篇,系列开始于 2021/01/01,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先把所有不带锁的题目刷完。 + +在这个系列文章里面,除了讲解解题思路以外,还会尽可能给出最为简洁的代码。如果涉及通解还会相应的代码模板。 + +为了方便各位同学能够电脑上进行调试和提交代码,我建立了相关的仓库:https://github.com/SharingSource/LogicStack-LeetCode 。 + +在仓库地址里,你可以看到系列文章的题解链接、系列文章的相应代码、LeetCode 原题链接和其他优选题解。 +