3. 无重复字符的最长子串【力扣】

题意理解

给定一个字符串,求最小无重复子串。

问题分析

滑动窗口

0923:本质上是一个动规的思想,从左向右挨个字符开头,求最长的无重复字符子串。

其他

算法思路要动笔,画盒图比较好,不能直接强记。

算法再分两层:一层是思想,归结到算法结构;一层是细节实现,归结到变量设置,变量的含义。看本题:思想是动规,从左到右每个字符开头,向后遍历得到最长子串。细节层面转化为实现两个指针,加一个字典或集合,两个指针指向子串的开头和结尾,字典和集合表征不重复。

    int lengthOfLongestSubstring(string s) {
        if(s.size()==0) return 0;
        
        int len=s.size();
        set<int> my_set{};    //保存滑动窗口字符集合,所求最小无重复子字符串
        int max_len=INT_MIN;
        int left=0, right=0;    //滑动窗口左右下标
        while(left<len && right < len) {    //遍历字符串
            char ch=s[right];
            cout << ch << endl;
            if(my_set.count(ch)) {    //如果当前字符存在在滑动窗口
                //cout << "exist" << endl;
                my_set.erase(s[left]);    //删窗口头元素
                left++;    //缩小窗口
            }
            else {    //不在
                //cout << "no exist" << endl;
                my_set.insert(ch);    //插入
                right++;    //扩大窗口
                int len_set=my_set.size();    //窗口大小
                //cout << len_set << endl;
                max_len=max(max_len, len_set);
            }
        }
        return max_len;
    }

链接

力扣

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        int cnt = s.size();
        if (cnt <= 1) return cnt;
        int low = 0, high = 0;
        int max_len = INT_MIN;
        unordered_map<char, int> my_dict;
        for (int low = 0; low < cnt; low ++) {
            //cout << "low " << low << endl;
            if (low != 0) {
                my_dict.erase(s[low-1]);     //删掉前一个
            }                
            while (high < cnt) {
                //cout << s[high] << endl;
                if (my_dict.count(s[high])) {
                    break;
                }
                else {
                    my_dict[s[high]]++;
                }
                high ++;
            }
            //cout << "high:" << high << endl;
            int cur_len = high - low;
            if (cur_len > max_len) max_len = cur_len;
        }
        return max_len;
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值