
详细解答请看代码注释
class Solution {
public:
int lengthOfLongestSubstring(string s) {
// 使用哈希集合来存储当前窗口中的字符,用于快速判断字符是否重复
unordered_set<char> uSet;
int ret = 0; // 存储最长无重复子串的长度
// 使用双指针i和j维护滑动窗口
// i: 窗口左边界,j: 窗口右边界
for(int i = 0, j = 0; j < s.size(); j++) {
// 关键步骤:当当前字符s[j]已经在集合中存在时(即出现重复)
// 不断从集合中移除s[i]并移动左指针i,直到窗口中不再有重复字符
while(uSet.count(s[j])) {
uSet.erase(s[i]); // 移除左边界字符
i++; // 左指针右移
}
// 将当前字符加入集合(现在窗口中肯定没有重复了)
uSet.insert(s[j]);
// 更新最大长度:当前窗口长度 = j - i + 1
ret = max(ret, j - i + 1);
}
return ret;
}
};
这里我想记一下关于set的函数:
begin() 返回set容器的第一个元素
end() 返回set容器的最后一个元素
clear() 删除set容器中的所有元素
empty() 判断set容器是否为空
max_size() 返回set容器可能包含的元素最大个数
size() 返回当前set容器中的元素个数
count() 用来查找set中某个键值出现的次数。因为set中不会出现重复的元素,因此该函数也就变成了判断某一键值是否在set中出现过
erase(iterator), 删除定位器iterator指向的值
erase(first, second) 删除定位器first和second之间的值
erase(key_value) 删除键值key_value的值
find(), 返回给定值的定位器,如果没找到则返回end()
insert(key_value) 将key_value插入到set中,返回值是pair ::iterator, bool>,bool标志着插入是否成功,而iterator代表插入的位置,若key_value已经在set中,则iterator表示的key_value在set中的位置。
insert(first, second) 将定位器first到second之间的元素插入到set中,返回值是void
lower_bound(key_value) 返回第一个大于等于key_value的定位器
upper_bound(key_value) 返回最后一个大于等于key_value的定位器
这两个也很重要,有时候寻找次大值的时候有用。
关于unordered_set和unordered_map
在C++中,unordered_set和unordered_map是两种基于哈希表的容器,它们都能提供高效的数据存储和访问。不过,它们之间存在一些关键的区别。
unordered_set 是一个集合容器,它存储的是唯一的元素,没有键值对的概念。你可以使用元素来进行查找、插入和删除操作。unordered_set使用哈希表来实现存储和查找,因此查找操作的复杂度为O(1)。例如,如果你需要存储一组不重复的整数或字符串,unordered_set是一个很好的选择。
unordered_map 则是一个关联容器,它存储的是键值对,每个键都是唯一的,可以使用键来访问对应的值。unordered_map同样使用哈希表来实现存储和查找,所以它的查找操作也具有O(1)的时间复杂度。当你需要存储一组键值对,并且需要通过键来快速访问对应的值时,unordered_map会更加合适。例如,实现一个单词到其定义的映射的字典,就可以使用unordered_map。
总结来说,unordered_map适用于需要存储键值对的场景,而unordered_set适用于需要存储唯一元素的场景。在选择使用哪一个时,需要根据实际的应用需求来决定。
在实际使用中,unordered_set和unordered_map的选择也受到存储元素类型的影响。如果元素本身就是需要存储的全部信息,那么unordered_set足以满足需求。但如果元素是由键和值组成的复合结构,且需要通过键来快速检索值,那么unordered_map则是更好的选择。
例如,如果你有一组学生的ID号,每个ID号都是唯一的,你只需要检查某个ID是否存在,或者需要存储一组不重复的ID号,那么unordered_set就能很好地完成这个任务。但如果你需要将每个学生的ID号映射到他们的成绩上,那么unordered_map就是必要的,因为它能够让你通过学生的ID快速找到对应的成绩。
在性能方面,由于unordered_set和unordered_map都是基于哈希表的,它们在插入、删除和查找操作上通常都能提供常数时间复杂度,这使得它们在处理大量数据时非常高效。然而,哈希表的性能也依赖于哈希函数的质量和冲突解决机制,因此在使用这些容器时,选择合适的哈希函数和调整哈希表的大小也是优化性能的重要方面。
在选择unordered_set和unordered_map时,还应考虑到它们的内存占用。由于unordered_map需要存储键和值,它通常会比unordered_set占用更多的内存。因此,如果内存使用是一个考虑因素,那么在只需要存储唯一元素而不需要映射到其他值的情况下,unordered_set可能是一个更节省内存的选择。
最后,虽然unordered_set和unordered_map提供了快速的数据操作,但它们不保证元素的顺序。如果你需要维护元素的某种顺序,那么可能需要考虑其他类型的容器,如set和map,它们基于红黑树实现,能够保持元素的有序性,但相应的操作时间复杂度为O(logN)。
上述内容以后复习看
630

被折叠的 条评论
为什么被折叠?



