From f70acb963a499e3a627d2358a4119b24649d74d7 Mon Sep 17 00:00:00 2001 From: speed <771935730@qq.com> Date: Thu, 7 Apr 2022 00:03:02 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=200763.=E5=88=92?= =?UTF-8?q?=E5=88=86=E5=AD=97=E6=AF=8D=E5=8C=BA=E9=97=B4.md=20=E6=96=B0?= =?UTF-8?q?=E5=A2=9E=E7=B1=BB=E4=BC=BC=E5=BC=95=E7=88=86=E6=B0=94=E7=90=83?= =?UTF-8?q?=E7=9A=84=E6=80=9D=E8=B7=AF=E4=BB=A5=E5=8F=8A=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0763.划分字母区间.md | 47 +++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/problems/0763.划分字母区间.md b/problems/0763.划分字母区间.md index 03d3a73b..d3958bd5 100644 --- a/problems/0763.划分字母区间.md +++ b/problems/0763.划分字母区间.md @@ -77,6 +77,53 @@ public: 但这道题目的思路是很巧妙的,所以有必要介绍给大家做一做,感受一下。 +## 补充 + +这里提供一种与[452.用最少数量的箭引爆气球](https://programmercarl.com/0452.用最少数量的箭引爆气球.html)、[435.无重叠区间](https://programmercarl.com/0435.无重叠区间.html)相同的思路。 + +统计字符串中所有字符的起始和结束位置,记录这些区间(实际上也就是[435.无重叠区间](https://programmercarl.com/0435.无重叠区间.html)题目里的输入),**将区间按左边界从小到大排序,找到边界将区间划分成组,互不重叠。找到的边界就是答案。** + +```CPP +class Solution { +public: + static bool cmp(vector &a, vector &b) { + return a[0] < b[0]; + } + // 记录每个字母出现的区间 + void countLabels(string s, vector> &hash) { + for (int i = 0; i < s.size(); ++i) { + if (hash[s[i] - 'a'][0] == INT_MIN) { + hash[s[i] - 'a'][0] = i; + } + hash[s[i] - 'a'][1] = i; + } + } + vector partitionLabels(string s) { + vector res; + vector> hash(26, vector(2, INT_MIN)); + countLabels(s, hash); + // 按照左边界从小到大排序 + sort(hash.begin(), hash.end(), cmp); + // 记录最大右边界 + int rightBoard = INT_MIN; + int leftBoard = 0; + for (int i = 0; i < hash.size(); ++i) { + // 过滤掉字符串中没有的字母 + if (hash[i][0] == INT_MIN) { + continue; + } + // 一旦下一区间左边界大于当前右边界,即可认为出现分割点 + if (rightBoard != INT_MIN && hash[i][0] > rightBoard) { + res.push_back(rightBoard - leftBoard + 1); + leftBoard = hash[i][0]; + } + rightBoard = max(rightBoard, hash[i][1]); + } + res.push_back(rightBoard - leftBoard + 1); + return res; + } +}; +``` ## 其他语言版本 From 3048b00d72146838275c37ec549b76eeca8813a9 Mon Sep 17 00:00:00 2001 From: speed Date: Thu, 7 Apr 2022 10:52:27 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BA=860763.=E5=88=92?= =?UTF-8?q?=E5=88=86=E5=AD=97=E6=AF=8D=E5=8C=BA=E9=97=B4.md=20=E6=96=B0?= =?UTF-8?q?=E5=A2=9E=E8=B4=AA=E5=BF=83=E6=80=9D=E8=B7=AF=E7=9A=84=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0763.划分字母区间.md | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/problems/0763.划分字母区间.md b/problems/0763.划分字母区间.md index d3958bd5..d350f255 100644 --- a/problems/0763.划分字母区间.md +++ b/problems/0763.划分字母区间.md @@ -90,35 +90,43 @@ public: return a[0] < b[0]; } // 记录每个字母出现的区间 - void countLabels(string s, vector> &hash) { + vector> countLabels(string s) { + vector> hash(26, vector(2, INT_MIN)); + vector> hash_filter; for (int i = 0; i < s.size(); ++i) { if (hash[s[i] - 'a'][0] == INT_MIN) { hash[s[i] - 'a'][0] = i; } hash[s[i] - 'a'][1] = i; } + // 去除字符串中未出现的字母所占用区间 + for (int i = 0; i < hash.size(); ++i) { + if (hash[i][0] != INT_MIN) { + hash_filter.push_back(hash[i]); + } + } + return hash_filter; } vector partitionLabels(string s) { vector res; - vector> hash(26, vector(2, INT_MIN)); - countLabels(s, hash); + // 这一步得到的 hash 即为无重叠区间题意中的输入样例格式:区间列表 + // 只不过现在我们要求的是区间分割点 + vector> hash = countLabels(s); // 按照左边界从小到大排序 sort(hash.begin(), hash.end(), cmp); // 记录最大右边界 - int rightBoard = INT_MIN; + int rightBoard = hash[0][1]; int leftBoard = 0; - for (int i = 0; i < hash.size(); ++i) { - // 过滤掉字符串中没有的字母 - if (hash[i][0] == INT_MIN) { - continue; - } + for (int i = 1; i < hash.size(); ++i) { + // 由于字符串一定能分割,因此, // 一旦下一区间左边界大于当前右边界,即可认为出现分割点 - if (rightBoard != INT_MIN && hash[i][0] > rightBoard) { + if (hash[i][0] > rightBoard) { res.push_back(rightBoard - leftBoard + 1); leftBoard = hash[i][0]; } rightBoard = max(rightBoard, hash[i][1]); } + // 最右端 res.push_back(rightBoard - leftBoard + 1); return res; }