leecode3.无重复字符的最长子串(滑动窗口)

无重复字符的最长子串

问题描述

给定一个字符串 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;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值