LeetCode-Day33——继续贪心
757. 设置交集大小至少为2
一个整数区间 [a, b] ( a < b ) 代表着从 a 到 b 的所有连续整数,包括 a 和 b。
给你一组整数区间intervals,请找到一个最小的集合 S,使得 S 里的元素与区间intervals中的每一个整数区间都至少有2个元素相交。
输出这个最小集合S的大小。
示例 1:
1 | 输入: intervals = [[1, 3], [1, 4], [2, 5], [3, 5]] |
示例 2:
1 | 输入: intervals = [[1, 2], [2, 3], [2, 4], [4, 5]] |
注意:
1 | intervals 的长度范围为[1, 3000]。 |
思路:
为了使集合S中的数字尽可能的少,我们希望处理区间的时候从小区间开始,如果区间b完全覆盖了区间a,那么和区间a有两个相同数字的集合一定也和区间b有两个相同的数字。同样,我们不希望一会儿处理一个前面的区间,一会儿处理后面一个区间,我们希望区间是有序的。如何排序?
我们按照结束位置从小往大排,当两个结束位置相同时,起始位置大的排前面处理,这也符合我们先处理小区间的原则。那么遍历区间的时候,当前区间就和我们维护的集合S有三种情况:
- 二者完全没有交集,这时候我们就需要从当前区间中取出两个数字加入集合S,那么取哪两个数呢?为了尽可能少使用数字,我们取当前区间中的最大两个数字,因为我们区间位置不断变大,所以取大的数字有更高的概率能和后面的区间有交集。
- 二者有一个数字的交集,那么这个交集数字一定是区间的起始位置,那么我们需要再取一个数字加入集合S,根据上面的分析,我们取最大的那个数,即区间的结束位置。
- 二者有两个以及两个数字以上的交集,我们不用做任何处理。
所以,Code如下:
1 | class Solution { |
763. 划分字母区间
字符串 S 由小写字母组成。我们要把这个字符串划分为尽可能多的片段,同一个字母只会出现在其中的一个片段。返回一个表示每个字符串片段的长度的列表。
示例 1:
1 | 输入: S = "ababcbacadefegdehijhklij" |
注意:
S的长度在[1, 500]之间。
S只包含小写字母’a’到’z’。
思路:其实这道题是map的一个应用。
首先遍历统计每个字母出现的最后的位置。
然后再遍历一遍,设置变量right用于表示分隔开的字符串的末尾在S里面的小标,变量left表示子字符串的开头在S里的下标
如果当前扫描的元素的最后一次出现的下标比right大,就说明字符串还需要延长,就刷新right
如果当前扫描的元素已经达到了right,就说明这个字符串已经完全找到了,就可以把答案添加到res中了。
Code如下:
1 | vector<int> result; |