力扣hot100_无重复字符的最长字串

详细解答请看代码注释

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_setunordered_map是两种基于哈希表的容器,它们都能提供高效的数据存储和访问。不过,它们之间存在一些关键的区别。

unordered_set 是一个集合容器,它存储的是唯一的元素,没有键值对的概念。你可以使用元素来进行查找、插入和删除操作。unordered_set使用哈希表来实现存储和查找,因此查找操作的复杂度为O(1)。例如,如果你需要存储一组不重复的整数或字符串,unordered_set是一个很好的选择。

unordered_map 则是一个关联容器,它存储的是键值对,每个键都是唯一的,可以使用键来访问对应的值。unordered_map同样使用哈希表来实现存储和查找,所以它的查找操作也具有O(1)的时间复杂度。当你需要存储一组键值对,并且需要通过键来快速访问对应的值时,unordered_map会更加合适。例如,实现一个单词到其定义的映射的字典,就可以使用unordered_map

总结来说,unordered_map适用于需要存储键值对的场景,而unordered_set适用于需要存储唯一元素的场景。在选择使用哪一个时,需要根据实际的应用需求来决定。

在实际使用中,unordered_setunordered_map的选择也受到存储元素类型的影响。如果元素本身就是需要存储的全部信息,那么unordered_set足以满足需求。但如果元素是由键和值组成的复合结构,且需要通过键来快速检索值,那么unordered_map则是更好的选择。

例如,如果你有一组学生的ID号,每个ID号都是唯一的,你只需要检查某个ID是否存在,或者需要存储一组不重复的ID号,那么unordered_set就能很好地完成这个任务。但如果你需要将每个学生的ID号映射到他们的成绩上,那么unordered_map就是必要的,因为它能够让你通过学生的ID快速找到对应的成绩。

在性能方面,由于unordered_setunordered_map都是基于哈希表的,它们在插入、删除和查找操作上通常都能提供常数时间复杂度,这使得它们在处理大量数据时非常高效。然而,哈希表的性能也依赖于哈希函数的质量和冲突解决机制,因此在使用这些容器时,选择合适的哈希函数和调整哈希表的大小也是优化性能的重要方面。

在选择unordered_setunordered_map时,还应考虑到它们的内存占用。由于unordered_map需要存储键和值,它通常会比unordered_set占用更多的内存。因此,如果内存使用是一个考虑因素,那么在只需要存储唯一元素而不需要映射到其他值的情况下,unordered_set可能是一个更节省内存的选择。

最后,虽然unordered_setunordered_map提供了快速的数据操作,但它们不保证元素的顺序。如果你需要维护元素的某种顺序,那么可能需要考虑其他类型的容器,如setmap,它们基于红黑树实现,能够保持元素的有序性,但相应的操作时间复杂度为O(logN)。

上述内容以后复习看

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值