无重复字符的最长子串
问题描述
给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。
示例
输入: s = “abcabcbb”
输出: 3
解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。
思路
优选代码学习
class Solution {
public:
int lengthOfLongestSubstring(string s) {
if(s.size() == 0) return 0;
unordered_set<char> lookup;
int maxStr = 0;
int left = 0;
for(int i = 0; i < s.size(); i++){
while (lookup.find(s[i]) != lookup.end()){
lookup.erase(s[left]);
left ++;
}
maxStr = max(maxStr,i-left+1);
lookup.insert(s[i]);
}
return maxStr;
}
};
unordered_set
1.unordered系列关联式容器
在C++98中,STL提供了底层为红黑树结构的一系列关联式容器,在查询时的效率可达到O(logN),即最差情况下需要比较红黑树的高度次,当树中的结点非常多时,查询效率也不理想。最好的查询是,进行很少的比较次数就能够将元素找到,因此在C++11中,STL又提供了4个unordered系列的关联式容器,这四个容器与红黑树结构的关联式容器使用方式基本类似,只是其底层结构不同。
2.unordered_set的介绍
unordered_set是不按特定顺序存储键值的关联式容器,其允许通过键值快速的索引到对应的元素
在unordered_set中,元素的值同时也是唯一地标识它的key。
在内部,unordered_set中的元素没有按照任何特定的顺序排序,为了能在常数范围内找到指定的key,unordered_set将相同哈希值的键值放在相同的桶中
unordered_set容器通过key访问单个元素要比set快,但它通常在遍历元素子集的范围迭代方面效率较低。
它的迭代器至少是前向迭代器。
3.unordered_set的使用
unordered_set的定义方式
方式一: 构造一个某类型的空容器。
unordered_set us1; //构造int类型的空容器
方式二: 拷贝构造某同类型容器的复制品。
unordered_set us2(us1); //拷贝构造同类型容器us1的复制品
方式三: 使用迭代器拷贝构造某一段内容。
string str(“abcedf”);
unordered_set us3(str.begin(), str.end()); //构造string对象某段区间的复制品
unordered_set接口的使用
unordered_set当中常用的成员函数如下:
成员函数 功能
insert 插入指定元素
erase 删除指定元素
find 查找指定元素
size 获取容器中元素的个数
empty 判断容器是否为空
clear 清空容器
swap 交换两个容器中的数据
count 获取容器中指定元素值的元素个数
unordered_set当中迭代器相关函数如下:
begin 获取容器中第一个元素的正向迭代器
end 获取容器中最后一个元素下一个位置的正向迭代器
滑动窗口代码
class Solution {
public:
int lengthOfLongestSubstring(string s) {
int l=0,n=s.length(),r=1;
int len=1,result=1;
if(n==0) return 0;
while(r<n)
{
for(int i=l;i<r;i++)
{
if(s[i]==s[r])
{
l=i+1;//遇到和右边界相同的元素,则将左指针移动到当前遍历元素的后一个位置
len=r-l;//计算滑动窗口的大小,此时不加1
break;
}
}
r++;
len++;//此处统一+1
result=max(len,result);
}
return result;
}
};
改进,桶
class Solution {
public:
int lengthOfLongestSubstring(string s) {
int l=0,n=s.length(),r=0,len=0;
vector<int> a(128,0);
while(r<n)
{
l=max(l,a[s[r]]);//更新左边界
a[s[r]]=r+1;//更新某一元素在字符串位置+1
len=max(len,r-l+1);
r++;
}
return len;
}
};