From f2459c79f32a7d20ca8f10d99f8c7fd36e1b7966 Mon Sep 17 00:00:00 2001 From: AC_Oier Date: Fri, 25 Nov 2022 10:35:38 +0800 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8feat:=20add=20809?= 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 + ...10\344\270\255\347\255\211\357\274\211.md" | 131 ++++++++++++++++++ 3 files changed, 133 insertions(+) create mode 100644 "LeetCode/801-810/809. \346\203\205\346\204\237\344\270\260\345\257\214\347\232\204\346\226\207\345\255\227\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 491a05f1..a2b1ed5f 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" @@ -38,6 +38,7 @@ | [719. 找出第 K 小的数对距离](https://leetcode.cn/problems/find-k-th-smallest-pair-distance/) | [LeetCode 题解链接](https://leetcode.cn/problems/find-k-th-smallest-pair-distance/solution/by-ac_oier-o4if/) | 困难 | 🤩🤩🤩🤩 | | [777. 在LR字符串中交换相邻字符](https://leetcode.cn/problems/swap-adjacent-in-lr-string/) | [LeetCode 题解链接](https://leetcode.cn/problems/swap-adjacent-in-lr-string/solution/by-ac_oier-ye71/) | 中等 | 🤩🤩🤩🤩 | | [786. 第 K 个最小的素数分数](https://leetcode-cn.com/problems/k-th-smallest-prime-fraction/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/k-th-smallest-prime-fraction/solution/gong-shui-san-xie-yi-ti-shuang-jie-you-x-8ymk/) | 中等 | 🤩🤩🤩 | +| [809. 情感丰富的文字](https://leetcode.cn/problems/expressive-words/) | [LeetCode 题解链接](https://leetcode.cn/problems/expressive-words/solution/by-ac_oier-tb57/) | 中等 | 🤩🤩🤩🤩🤩 | | [825. 适龄的朋友](https://leetcode-cn.com/problems/friends-of-appropriate-ages/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/friends-of-appropriate-ages/solution/gong-shui-san-xie-yi-ti-shuang-jie-pai-x-maa8/) | 中等 | 🤩🤩🤩🤩 | | [832. 翻转图像](https://leetcode-cn.com/problems/flipping-an-image/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/flipping-an-image/solution/shuang-zhi-zhen-yi-bian-chu-li-huan-you-ik0v1/) | 简单 | 🤩🤩 | | [838. 推多米诺](https://leetcode-cn.com/problems/push-dominoes/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/push-dominoes/solution/gong-shui-san-xie-yi-ti-shuang-jie-bfs-y-z52w/) | 中等 | 🤩🤩🤩🤩 | diff --git "a/Index/\346\250\241\346\213\237.md" "b/Index/\346\250\241\346\213\237.md" index 33215eaf..ae281fa5 100644 --- "a/Index/\346\250\241\346\213\237.md" +++ "b/Index/\346\250\241\346\213\237.md" @@ -110,6 +110,7 @@ | [796. 旋转字符串](https://leetcode-cn.com/problems/rotate-string/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/rotate-string/solution/by-ac_oier-bnkx/) | 简单 | 🤩🤩🤩 | | [804. 唯一摩尔斯密码词](https://leetcode-cn.com/problems/unique-morse-code-words/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/unique-morse-code-words/solution/by-ac_oier-a9hv/) | 简单 | 🤩🤩🤩 | | [806. 写字符串需要的行数](https://leetcode-cn.com/problems/number-of-lines-to-write-string/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/number-of-lines-to-write-string/solution/by-ac_oier-5hg2/) | 简单 | 🤩🤩🤩🤩 | +| [809. 情感丰富的文字](https://leetcode.cn/problems/expressive-words/) | [LeetCode 题解链接](https://leetcode.cn/problems/expressive-words/solution/by-ac_oier-tb57/) | 中等 | 🤩🤩🤩🤩 | | [811. 子域名访问计数](https://leetcode.cn/problems/subdomain-visit-count/) | [LeetCode 题解链接](https://leetcode.cn/problems/subdomain-visit-count/solution/by-ac_oier-aex6/) | 中等 | 🤩🤩🤩🤩 | | [812. 最大三角形面积](https://leetcode.cn/problems/largest-triangle-area/) | [LeetCode 题解链接](https://leetcode.cn/problems/largest-triangle-area/solution/by-ac_oier-htv8/) | 简单 | 🤩🤩🤩🤩 | | [816. 模糊坐标](https://leetcode.cn/problems/ambiguous-coordinates/) | [LeetCode 题解链接](https://leetcode.cn/problems/ambiguous-coordinates/solution/by-ac_oier-sbxl/) | 中等 | 🤩🤩🤩🤩 | diff --git "a/LeetCode/801-810/809. \346\203\205\346\204\237\344\270\260\345\257\214\347\232\204\346\226\207\345\255\227\357\274\210\344\270\255\347\255\211\357\274\211.md" "b/LeetCode/801-810/809. \346\203\205\346\204\237\344\270\260\345\257\214\347\232\204\346\226\207\345\255\227\357\274\210\344\270\255\347\255\211\357\274\211.md" new file mode 100644 index 00000000..434be79d --- /dev/null +++ "b/LeetCode/801-810/809. \346\203\205\346\204\237\344\270\260\345\257\214\347\232\204\346\226\207\345\255\227\357\274\210\344\270\255\347\255\211\357\274\211.md" @@ -0,0 +1,131 @@ +### 题目描述 + +这是 LeetCode 上的 **[809. 情感丰富的文字](https://leetcode.cn/problems/expressive-words/solution/by-ac_oier-tb57/)** ,难度为 **中等**。 + +Tag : 「双指针」、「模拟」 + + + +有时候人们会用重复写一些字母来表示额外的感受,比如 `"hello" -> "heeellooo", "hi" -> "hiii"`。我们将相邻字母都相同的一串字符定义为相同字母组,例如:`"h", "eee", "ll", "ooo"`。 + +对于一个给定的字符串 `S` ,如果另一个单词能够通过将一些字母组扩张从而使其和 `S` 相同,我们将这个单词定义为可扩张的(`stretchy`)。扩张操作定义如下:选择一个字母组(包含字母 `c` ),然后往其中添加相同的字母 `c` 使其长度达到 `3` 或以上。 + +例如,以 `"hello"` 为例,我们可以对字母组 `"o"` 扩张得到 `"hellooo"`,但是无法以同样的方法得到 `"helloo"` 因为字母组 `"oo"` 长度小于 `3`。此外,我们可以进行另一种扩张 `"ll" -> "lllll"` 以获得 `"helllllooo"`。如果 `S = "helllllooo"`,那么查询词 `"hello"` 是可扩张的,因为可以对它执行这两种扩张操作使得 `query = "hello" -> "hellooo" -> "helllllooo" = S`。 + +输入一组查询单词,输出其中可扩张的单词数量。 + +示例: +``` +输入: +S = "heeellooo" +words = ["hello", "hi", "helo"] + +输出:1 + +解释: +我们能通过扩张 "hello" 的 "e" 和 "o" 来得到 "heeellooo"。 +我们不能通过扩张 "helo" 来得到 "heeellooo" 因为 "ll" 的长度小于 3 。 +``` + +提示: +* $0 <= len(S) <= 100$ +* $0 <= len(words) <= 100$ +* $0 <= len(words[i]) <= 100$ +* `S` 和所有在 `words` 中的单词都只由小写字母组成。 + +--- + +### 双指针 + +该题最难的部分就是理解 “扩张” 操作:假设有两个字符相同的连续段 `a` 和 `b`,如何判断 `a` 是否能由 `b` 扩张而来。 + +忘记掉题目所说的规则,我们重新定义 “扩张” 操作: + +* 当 `a` 和 `b` 长度相同,定义为可扩张; +* 当 `a` 和 `b` 长度不同,根据「`a` 和 `b` 长度对比」以及「`a` 的长度大小」分情况讨论: + * 当 `b` 长度大于 `a`,不可扩张; + * 当 `a` 长度大于 `b`,**我们不一定要拿整一段的 `b` 进行扩张,可以拿 `b` 中的一个字符进行扩张。** 因此只需要满足扩张后的长度(`a` 的长度)大于 $3$ 即可定义为可扩张。 + +搞明白何为 “扩张” 后,剩余的则是简单的「双指针 + 模拟」做法。 + +Java 代码: +```Java +class Solution { + public int expressiveWords(String s, String[] words) { + int n = s.length(), ans = 0; + out:for (String word : words) { + int m = word.length(), i = 0, j = 0; + while (i < n && j < m) { + if (s.charAt(i) != word.charAt(j)) continue out; + int a = i, b = j; + while (a < n && s.charAt(a) == s.charAt(i)) a++; + while (b < m && word.charAt(b) == word.charAt(j)) b++; + a -= i; b -= j; + if (a != b && (b > a || a < 3)) continue out; + i += a; j += b; + } + if (i == n && j == m) ans++; + } + return ans; + } +} +``` +TypeScript 代码: +```TypeScript +function expressiveWords(s: string, words: string[]): number { + let n = s.length, ans = 0 + out:for (const word of words) { + let m = word.length, i = 0, j = 0 + while (i < n && j < m) { + if (s[i] != word[j]) continue out + let a = i, b = j + while (a < n && s[a] == s[i]) a++ + while (b < m && word[b] == word[j]) b++ + a -= i; b -= j; + if (a != b && (b > a || a < 3)) continue out + i += a; j += b; + } + if (i == n && j == m) ans++; + } + return ans +} +``` +Python 代码: +```Python +class Solution: + def expressiveWords(self, s: str, words: List[str]) -> int: + n, ans = len(s), 0 + for word in words: + m, i, j = len(word), 0, 0 + ok = True + while ok and i < n and j < m: + if s[i] != word[j]: + ok = False + a, b = i, j + while a < n and s[a] == s[i]: + a += 1 + while b < m and word[b] == word[j]: + b += 1 + a, b = a - i, b - j + if a != b and (b > a or a < 3): + ok = False + i, j = i + a, j + b + if ok and i == n and j == m: + ans += 1 + return ans +``` +* 时间复杂度:$O(n \times m + \sum_{i = 0}^{m - 1}words[i].length)$,其中 `n` 为字符串 `s` 的长度,`m` 为数组 `words` 的长度 +* 空间复杂度:$O(1)$ + +--- + +### 最后 + +这是我们「刷穿 LeetCode」系列文章的第 `No.809` 篇,系列开始于 2021/01/01,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先把所有不带锁的题目刷完。 + +在这个系列文章里面,除了讲解解题思路以外,还会尽可能给出最为简洁的代码。如果涉及通解还会相应的代码模板。 + +为了方便各位同学能够电脑上进行调试和提交代码,我建立了相关的仓库:https://github.com/SharingSource/LogicStack-LeetCode 。 + +在仓库地址里,你可以看到系列文章的题解链接、系列文章的相应代码、LeetCode 原题链接和其他优选题解。 +