【中等】3. 无重复字符的最长子串

unordered_set occ
 unordered_set<char> occ;
std::unordered_set class template

Unordered Set

无序集

Unordered sets are containers that store unique elements in no particular order, and which allow for fast retrieval of individual elements based on their value.

无序集是不按特定顺序存储唯一元素的容器,它允许根据元素的值快速检索单个元素。

In an unordered_set, the value of an element is at the same time its key, that identifies it uniquely. Keys are immutable, therefore, the elements in an unordered_set cannot be modified once in the container - they can be inserted and removed, though.

在无序的_集合中,元素的值同时是其唯一标识它的键。键是不可变的,因此,无序_集中的元素在容器中一次不能被修改——尽管它们可以被插入和删除。

Internally, the elements in the unordered_set are not sorted in any particular order, but organized into buckets depending on their hash values to allow for fast access to individual elements directly by their values (with a constant average time complexity on average).

在内部,无序_集中的元素没有按任何特定顺序排序,而是根据它们的散列值组织成桶,以允许直接通过它们的值快速访问单个元素(平均时间复杂度恒定)。

unordered_set containers are faster than set containers to access individual elements by their key, although they are generally less efficient for range iteration through a subset of their elements.

无序的集合容器比集合容器更快地通过键访问单个元素,尽管它们在通过元素子集进行范围迭代时通常效率较低。

Iterators in the container are at least forward iterators.

容器中的迭代器至少是正向迭代器。 alt

unordered_set.erase
  occ.erase(s[i - 1]);
std::unordered_set::erase public member function

Erase elements

删除元素

Removes from the unordered_set container either a single element or a range of elements ([first,last)).

从无序的_集容器中移除单个元素或一系列元素([first,last])。

This effectively reduces the container size by the number of elements removed, calling each element's destructor.

这将通过调用每个元素的析构函数,有效地减少移除的元素数,从而减小容器的大小。 alt

unordered_set.count
  while (rk + 1 < n && !occ.count(s[rk + 1])) {}
std::unordered_set::count public member function

Count elements with a specific key

使用特定键对元素进行计数

Searches the container for elements with a value of k and returns the number of elements found. Because unordered_set containers do not allow for duplicate values, this means that the function actually returns 1 if an element with that value exists in the container, and zero otherwise.

在容器中搜索值为k的元素,并返回找到的元素数。因为无序的_集容器不允许重复值,这意味着如果容器中存在具有该值的元素,函数实际上返回1,否则返回0。 alt

unordered_set.insert
  occ.insert(s[rk + 1]);
std::unordered_set::count public member function

Insert elements

插入元素

Inserts new elements in the unordered_set.

在无序的集合中插入新元素。

Each element is inserted only if it is not equivalent to any other element already in the container (elements in an unordered_set have unique values).

仅当每个元素不等同于容器中已有的任何其他元素(无序_集中的元素具有唯一值)时,才会插入该元素。

This effectively increases the container size by the number of elements inserted.

这将通过插入的元素数量有效地增加容器大小。

The parameters determine how many elements are inserted and to which values they are initialized:

这些参数决定了插入的元素数量及其初始化值: alt

max
  ans = max(ans, rk - i + 1);
std::max function template

Return the largest

返回最大的

Returns the largest of a and b. If both are equivalent, a is returned.

返回a和b中的最大值。如果两者相等,则返回a。

The versions for initializer lists (3) return the largest of all the elements in the list. Returning the first of them if these are more than one.

初始值设定项列表的版本(3)返回列表中所有元素中最大的一个。如果它们不止一个,则返回第一个。

The function uses operator< (or comp, if provided) to compare the values.

该函数使用运算符<(或comp,如果提供)来比较值。 alt

3. 无重复字符的最长子串

给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。

滑动窗口
class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        // 哈希集合,记录每个字符是否出现过
        unordered_set<char> occ;//一种数据结构来判断 是否有重复的字符,常用的数据结构为哈希集合(即 C++ 中的 std::unordered_set,Java 中的 HashSet,Python 中的 set, JavaScript 中的 Set)。
        int n = s.size();
        // 右指针,初始值为 -1,相当于在字符串的左边界的左侧,还没有开始移动
        int rk = -1, ans = 0;//使用两个指针表示字符串中的某个子串(或窗口)的左右边界,其中左指针代表着「枚举子串的起始位置」,而右指针即为 r_k;
        // 枚举左指针的位置,初始值隐性地表示为 -1
        for (int i = 0; i < n; ++i) {//将左指针向右移动一格,表示 开始枚举下一个字符作为起始位置,
            if (i != 0) {
                // 左指针向右移动一格,移除一个字符
                occ.erase(s[i - 1]);//在左指针向右移动的时候,从哈希集合中移除一个字符,
            }
            while (rk + 1 < n && !occ.count(s[rk + 1])) {//不断地向右移动右指针,但需要保证这两个指针对应的子串中没有重复的字符。
                // 不断地移动右指针
                occ.insert(s[rk + 1]);//在右指针向右移动的时候,往哈希集合中添加一个字符。
                ++rk;
            }
            // 第 i 到 rk 个字符是一个极长的无重复字符子串
            ans = max(ans, rk - i + 1);//在移动结束后,这个子串就对应着 以左指针开始的,不包含重复字符的最长子串。记录下这个子串的长度;
        }
        return ans;//在枚举结束后,找到的最长的子串的长度即为答案。
    }
};
力扣题解 文章被收录于专栏

边做边写 参考力扣官方题解和《数据结构:C语言描述(第3版)》

全部评论

相关推荐

10-30 22:18
已编辑
毛坦厂中学 C++
点赞 评论 收藏
分享
球球别再泡了:坏,我单9要了14
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务