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 73b95b28..43361965 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" @@ -12,6 +12,7 @@ | [75. 颜色分类](https://leetcode.cn/problems/sort-colors/) | [LeetCode 题解链接](https://leetcode.cn/problems/sort-colors/solution/by-ac_oier-7lwk/) | 中等 | 🤩🤩🤩🤩 | | [88. 合并两个有序数组](https://leetcode-cn.com/problems/merge-sorted-array/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/merge-sorted-array/solution/gong-shui-san-xie-yi-ti-san-jie-shuang-z-47gj/) | 简单 | 🤩🤩🤩 | | [141. 环形链表](https://leetcode.cn/problems/linked-list-cycle/) | [LeetCode 题解链接](https://leetcode.cn/problems/linked-list-cycle/solution/by-ac_oier-lfgr/) | 简单 | 🤩🤩🤩🤩 | +| [142. 环形链表 II](https://leetcode.cn/problems/linked-list-cycle-ii/) | [LeetCode 题解链接](https://leetcode.cn/problems/linked-list-cycle-ii/solution/by-ac_oier-xw16/) | 中等 | 🤩🤩🤩🤩 | | [345. 反转字符串中的元音字母](https://leetcode-cn.com/problems/reverse-vowels-of-a-string/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/reverse-vowels-of-a-string/solution/gong-shui-san-xie-note-bie-pian-shuang-z-c8ii/) | 简单 | 🤩🤩🤩 | | [395. 至少有 K 个重复字符的最长子串](https://leetcode-cn.com/problems/longest-substring-with-at-least-k-repeating-characters/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/longest-substring-with-at-least-k-repeating-characters/solution/xiang-jie-mei-ju-shuang-zhi-zhen-jie-fa-50ri1/) | 中等 | 🤩🤩🤩 | | [413. 等差数列划分](https://leetcode-cn.com/problems/arithmetic-slices/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/arithmetic-slices/solution/gong-shui-san-xie-shuang-zhi-zhen-qiu-ji-ef1q/) | 中等 | 🤩🤩🤩🤩 | diff --git "a/Index/\346\240\210.md" "b/Index/\346\240\210.md" index 893c4c31..52c88413 100644 --- "a/Index/\346\240\210.md" +++ "b/Index/\346\240\210.md" @@ -11,6 +11,7 @@ | [636. 函数的独占时间](https://leetcode.cn/problems/exclusive-time-of-functions/) | [LeetCode 题解链接](https://leetcode.cn/problems/exclusive-time-of-functions/solution/by-ac_oier-z3ed/) | 中等 | 🤩🤩🤩🤩🤩 | | [726. 原子的数量](https://leetcode-cn.com/problems/number-of-atoms/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/number-of-atoms/solution/gong-shui-san-xie-shi-yong-xiao-ji-qiao-l5ak4/) | 困难 | 🤩🤩🤩🤩 | | [735. 行星碰撞](https://leetcode.cn/problems/asteroid-collision/) | [LeetCode 题解链接](https://leetcode.cn/problems/asteroid-collision/solution/by-ac_oier-p4qh/) | 中等 | 🤩🤩🤩🤩🤩 | +| [856. 括号的分数](https://leetcode.cn/problems/score-of-parentheses/) | [LeetCode 题解链接](https://leetcode.cn/problems/score-of-parentheses/solution/by-ac_oier-0mhz/) | 中等 | 🤩🤩🤩🤩🤩 | | [946. 验证栈序列](https://leetcode.cn/problems/validate-stack-sequences/) | [LeetCode 题解链接](https://leetcode.cn/problems/validate-stack-sequences/solution/by-ac_oier-84qd/) | 中等 | 🤩🤩🤩🤩 | | [1190. 反转每对括号间的子串](https://leetcode-cn.com/problems/reverse-substrings-between-each-pair-of-parentheses/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/reverse-substrings-between-each-pair-of-parentheses/solution/gong-shui-san-xie-shi-yong-shuang-duan-d-r35q/) | 中等 | 🤩🤩🤩🤩🤩 | | [1598. 文件夹操作日志搜集器](https://leetcode.cn/problems/crawler-log-folder/) | [LeetCode 题解链接](https://leetcode.cn/problems/crawler-log-folder/solution/by-ac_oier-24xb/) | 简单 | 🤩🤩🤩 | diff --git "a/Index/\351\223\276\350\241\250.md" "b/Index/\351\223\276\350\241\250.md" index 41947f42..83a36124 100644 --- "a/Index/\351\223\276\350\241\250.md" +++ "b/Index/\351\223\276\350\241\250.md" @@ -12,6 +12,7 @@ | [92. 反转链表 II](https://leetcode-cn.com/problems/reverse-linked-list-ii/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/reverse-linked-list-ii/solution/yi-ge-neng-ying-yong-suo-you-lian-biao-t-vjx6/) | 中等 | 🤩🤩🤩 | | [138. 复制带随机指针的链表](https://leetcode-cn.com/problems/copy-list-with-random-pointer/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/copy-list-with-random-pointer/solution/gong-shui-san-xie-yi-ti-shuang-jie-ha-xi-pqek/) | 中等 | 🤩🤩🤩 | | [141. 环形链表](https://leetcode.cn/problems/linked-list-cycle/) | [LeetCode 题解链接](https://leetcode.cn/problems/linked-list-cycle/solution/by-ac_oier-lfgr/) | 简单 | 🤩🤩🤩🤩 | +| [142. 环形链表 II](https://leetcode.cn/problems/linked-list-cycle-ii/) | [LeetCode 题解链接](https://leetcode.cn/problems/linked-list-cycle-ii/solution/by-ac_oier-xw16/) | 中等 | 🤩🤩🤩🤩 | | [160. 相交链表](https://leetcode-cn.com/problems/intersection-of-two-linked-lists/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/intersection-of-two-linked-lists/solution/gong-shui-san-xie-zhao-liang-tiao-lian-b-h3bd/) | 简单 | 🤩🤩🤩🤩🤩 | | [146. LRU 缓存机制](https://leetcode-cn.com/problems/lru-cache/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/lru-cache/solution/gong-shui-san-xie-she-ji-shu-ju-jie-gou-68hv2/) | 中等 | 🤩🤩🤩🤩🤩 | | [203. 移除链表元素](https://leetcode-cn.com/problems/remove-linked-list-elements/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/remove-linked-list-elements/solution/gong-shui-san-xie-yi-chu-lian-biao-yuan-ca6fu/) | 简单 | 🤩🤩🤩 | diff --git "a/LeetCode/141-150/142. \347\216\257\345\275\242\351\223\276\350\241\250 II\357\274\210\344\270\255\347\255\211\357\274\211.md" "b/LeetCode/141-150/142. \347\216\257\345\275\242\351\223\276\350\241\250 II\357\274\210\344\270\255\347\255\211\357\274\211.md" new file mode 100644 index 00000000..e7350f53 --- /dev/null +++ "b/LeetCode/141-150/142. \347\216\257\345\275\242\351\223\276\350\241\250 II\357\274\210\344\270\255\347\255\211\357\274\211.md" @@ -0,0 +1,101 @@ +### 题目描述 + +这是 LeetCode 上的 **[142. 环形链表 II](https://leetcode.cn/problems/linked-list-cycle-ii/solution/by-ac_oier-xw16/)** ,难度为 **中等**。 + +Tag : 「链表」、「快慢指针」、「双指针」 + + + +给定一个链表的头节点  `head`,返回链表开始入环的第一个节点。 如果链表无环,则返回 `null`。 + +如果链表中有某个节点,可以通过连续跟踪 `next` 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 `pos` 来表示链表尾连接到链表中的位置(索引从 `0` 开始)。如果 `pos` 是 `-1`,则在该链表中没有环。 + +注意:`pos` 不作为参数进行传递,仅仅是为了标识链表的实际情况。 + +不允许修改 链表。 + +示例 1: +![](https://assets.leetcode.com/uploads/2018/12/07/circularlinkedlist.png) +``` +输入:head = [3,2,0,-4], pos = 1 + +输出:返回索引为 1 的链表节点 + +解释:链表中有一个环,其尾部连接到第二个节点。 +``` +示例 2: +![](https://assets.leetcode-cn.com/aliyun-lc-upload/uploads/2018/12/07/circularlinkedlist_test2.png) +``` +输入:head = [1,2], pos = 0 + +输出:返回索引为 0 的链表节点 + +解释:链表中有一个环,其尾部连接到第一个节点。 +``` +示例 3: +![](https://assets.leetcode-cn.com/aliyun-lc-upload/uploads/2018/12/07/circularlinkedlist_test3.png) +``` +输入:head = [1], pos = -1 + +输出:返回 null + +解释:链表中没有环。 +``` + +提示: +* 链表中节点的数目范围在范围 $[0, 10^4]$ 内 +* $-10^5 <= Node.val <= 10^5$ +* `pos` 的值为 `-1` 或者链表中的一个有效索引 + +进阶:你是否可以使用 $O(1)$ 空间解决此题? + +--- + +### 快慢指针 + +起始使用 `slow` 和 `fast` 作为慢快指针(`slow` 每次走一步,`fast` 每次走两步),起始均为 `head`。 + +若 `fast` 顺利走到结尾,说明链表无环,直接返回 `null`; + +若两者成功相遇,说明链表有环。我们定义链表起点到环入口距离为 `x`,环内节点数量为 `y`。那么从链表起点到环入口的任意路径都能归纳成 $x + k \times y$(其中 $k$ 为大于等于 $0$ 的任意值)。 + +当两者首次相遇时,假设 `slow` 走的距离为 `d1`,而 `fast` 走的距离为 `d2`,根据速度差定义可知 $d2 = d1 \times 2$。同时根据 [141. 环形链表](https://leetcode.cn/problems/linked-list-cycle/solution/by-ac_oier-lfgr/) 结论,两者必然在环中相遇,且必然是 `fast` 在环内从后面追上 `slow`,因此 `d2` 相比于 `d1` 必然是多了 `y` 的整数倍,即有 $d2 = d1 + m \times y$(其中 $m$ 为圈数),即可推导出 $d1 = m \times y$。 + +同时根据链表起点到环入口的任意路径均表示为 $x + k \times y$,我们知道如果 `slow` 再走 `x` 步会到达环入口,同时链表起点到环入口也是 `x` 步,因此我们可以复用 `fast`,将其复位到链表起点,和 `slow` 一起每次往前一步,当两者再次相遇,必然是同时位于环入口。 + +同时该做法容易拓展成求 `x` 和求 `y` 等问题。 + +代码: +```Java +public class Solution { + public ListNode detectCycle(ListNode head) { + ListNode base = head; + ListNode slow = head, fast = head; + boolean ok = false; + while (!ok && fast != null && fast.next != null) { + slow = slow.next; fast = fast.next.next; + if (slow == fast) ok = true; + } + if (!ok) return null; + fast = head; + while (slow != fast) { + slow = slow.next; fast = fast.next; + } + return slow; + } +} +``` +* 时间复杂度:$O(n)$ +* 空间复杂度:$O(1)$ + +--- + +### 最后 + +这是我们「刷穿 LeetCode」系列文章的第 `No.142` 篇,系列开始于 2021/01/01,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先把所有不带锁的题目刷完。 + +在这个系列文章里面,除了讲解解题思路以外,还会尽可能给出最为简洁的代码。如果涉及通解还会相应的代码模板。 + +为了方便各位同学能够电脑上进行调试和提交代码,我建立了相关的仓库:https://github.com/SharingSource/LogicStack-LeetCode 。 + +在仓库地址里,你可以看到系列文章的题解链接、系列文章的相应代码、LeetCode 原题链接和其他优选题解。 diff --git "a/LeetCode/851-860/856. \346\213\254\345\217\267\347\232\204\345\210\206\346\225\260\357\274\210\344\270\255\347\255\211\357\274\211.md" "b/LeetCode/851-860/856. \346\213\254\345\217\267\347\232\204\345\210\206\346\225\260\357\274\210\344\270\255\347\255\211\357\274\211.md" new file mode 100644 index 00000000..f5203404 --- /dev/null +++ "b/LeetCode/851-860/856. \346\213\254\345\217\267\347\232\204\345\210\206\346\225\260\357\274\210\344\270\255\347\255\211\357\274\211.md" @@ -0,0 +1,116 @@ +### 题目描述 + +这是 LeetCode 上的 **[856. 括号的分数](https://leetcode.cn/problems/score-of-parentheses/solution/by-ac_oier-0mhz/)** ,难度为 **中等**。 + +Tag : 「栈」 + + + +给定一个平衡括号字符串 `S`,按下述规则计算该字符串的分数: + +* `()` 得 `1` 分。 +* `AB` 得 `A + B` 分,其中 `A` 和 `B` 是平衡括号字符串。 +* `(A)` 得 `2 * A` 分,其中 `A` 是平衡括号字符串。 + +示例 1: +``` +输入: "()" + +输出: 1 +``` +示例 2: +``` +输入: "(())" + +输出: 2 +``` +示例 3: +``` +输入: "()()" + +输出: 2 +``` +示例 4: +``` +输入: "(()(()))" + +输出: 6 +``` + +提示: +* `S` 是平衡括号字符串,且只含有 `(` 和 `)` 。 +* $2 <= S.length <= 50$ + +--- + +### 栈 + +初始化将答案 `0` 放入栈中,从前往后处理整个 `s`,当遇到 `(` 则存入一个占位数值 `0`,遇到 `)` 取出栈顶元素 `cur`,根据栈顶元素数值值分情况讨论: + +* 栈顶元素 $cur = 0$,即当前的 `)` 的前一元素即是 `(` ,根据 `()` 得一分的规则可知,我们本次操作得到的分值为 $1$; +* 栈顶元素 $cur \neq 0$,即当前 `)` 与其匹配的 `(` 中间相隔了其他字符,根据 `(A)` 的得分规则,此时可知得分为 $cur \times 2$; + +将两者结合可统一为 $\max(cur \times 2, 1)$。 + +由于我们每次遇到 `)` 时,都将最近一次操作计算出来。而再前面无论是 `)` 还是 `(` 我们都可以归结到 `X()` 的相邻项累加规则,将其新得分累加到栈顶元素上,其中 `(` 仍采用累加规则,则利用我们将 `(` 定义为 $0$ 的设定。 + +Java 代码: +```Java +class Solution { + public int scoreOfParentheses(String s) { + Deque d = new ArrayDeque<>(); + d.addLast(0); + for (char c : s.toCharArray()) { + if (c == '(') d.addLast(0); + else { + int cur = d.pollLast(); + d.addLast(d.pollLast() + Math.max(cur * 2 , 1)); + } + } + return d.peekLast(); + } +} +``` +TypeScript 代码: +```TypeScript +function scoreOfParentheses(s: string): number { + const stk = new Array() + stk.push(0) + for (const c of s) { + if (c == '(') stk.push(0) + else { + const cur = stk.pop() + stk.push(stk.pop() + Math.max(cur * 2, 1)) + } + } + return stk.pop() +} +``` +Python 代码: +```Python +class Solution: + def scoreOfParentheses(self, s: str) -> int: + stk = [0] + for c in s: + if c == '(': + stk.append(0) + else: + cur = stk.pop() + stk.append(stk.pop() + max(cur * 2, 1)) + return stk[-1] +``` +* 时间复杂度:$O(n)$ +* 空间复杂度:$O(n)$ + +--- + +### 最后 + +这是我们「刷穿 LeetCode」系列文章的第 `No.856` 篇,系列开始于 2021/01/01,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先把所有不带锁的题目刷完。 + +在这个系列文章里面,除了讲解解题思路以外,还会尽可能给出最为简洁的代码。如果涉及通解还会相应的代码模板。 + +为了方便各位同学能够电脑上进行调试和提交代码,我建立了相关的仓库:https://github.com/SharingSource/LogicStack-LeetCode 。 + +在仓库地址里,你可以看到系列文章的题解链接、系列文章的相应代码、LeetCode 原题链接和其他优选题解。 +