diff --git a/problems/0763.划分字母区间.md b/problems/0763.划分字母区间.md index 03d3a73b..d350f255 100644 --- a/problems/0763.划分字母区间.md +++ b/problems/0763.划分字母区间.md @@ -77,6 +77,61 @@ 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]; + } + // 记录每个字母出现的区间 + 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; + // 这一步得到的 hash 即为无重叠区间题意中的输入样例格式:区间列表 + // 只不过现在我们要求的是区间分割点 + vector> hash = countLabels(s); + // 按照左边界从小到大排序 + sort(hash.begin(), hash.end(), cmp); + // 记录最大右边界 + int rightBoard = hash[0][1]; + int leftBoard = 0; + for (int i = 1; i < hash.size(); ++i) { + // 由于字符串一定能分割,因此, + // 一旦下一区间左边界大于当前右边界,即可认为出现分割点 + 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; + } +}; +``` ## 其他语言版本