• 滑动窗口


    双指针思想,i为慢指针,指向当前子串开始位置,j为快指针,指向当前判断的字符
    idx[s[j]]记录字符s[j]上次出现的位置
    每次迭代记录字符出现位置
    当字符s[j]上次出现的位置大于当前子串开始位置i时,比较当前子串长度与目前为止所有子串最大长度,取最大,同时将开始位置设为字符s[j]上次出现位置的下一位

    class Solution {
    public:
        int lengthOfLongestSubstring(string s) {
            int res = 0, i = 0, j = 0;
            vector<int> idx(128, -1);
            while(j < s.size())
            {
                if(idx[s[j]] >= i)
                {
                    res = max(res, j - i);
                    i = idx[s[j]] + 1;         
                }
                idx[s[j++]] = j;
            }
            res = max(res, j - i);
            return res;
        }
    };

    76. 最小覆盖子串

    难度困难

    给你一个字符串 S、一个字符串 T,请在字符串 S 里面找出:包含 T 所有字符的最小子串。

    示例:

    输入: S = "ADOBECODEBANC", T = "ABC"
    输出: "BANC"

    说明:

    • 如果 S 中不存这样的子串,则返回空字符串 ""
    • 如果 S 中存在这样的子串,我们保证它是唯一的答案。

    思路:

    用哈希表完成,由于匹配数组t可能存在重复值,所以map数值需要是int。
    总体算法模拟音乐音量上下浮动,t 的元素个数就是音量高度,t 以外的其他元素都为 0,
    遍历 s 的过程中,遇到一个音则将其减少一个音量.(* t 数组以外的音量不可能大于 0)
    搜索过程中,指定音量下降计数 cnt 增加,减小到 0 以下不算在内,
    当减少总数等于 t 的总数时,所有数就齐了,计算长度。
    随后进行回退,如果是 t 以外的音,其增加不改变计数 cnt,直到遇到 t 中的音,
    且该值在map中大于0时(区间中 t 的某一个音大于其原始的数量,它map的值可能会小于0),
    回退停止,继续向前搜索,重复 步骤 2。
    细节:

    需要匹配的数组t用unordered_map,查找O(1), 其实如果知道是字母用vector完全够用,但map可拓展性更强一些。
    而普通的map是有序二叉树结构,需要二分查找O(log2(n)),不适用于反复进行读取数组的情况。
    字符串提取在最后返回时进行,防止过程中反复提取产生消耗。故根据substr(),只要记忆起点和长度就行。
    代码

    class Solution {
    public:
        string minWindow(string s, string t) {
            unordered_map<char, int> map;
            for (auto c : t) map[c]++;
            int left = 0, cnt = 0, maxlen = s.size() + 1, start = left;
            for (int i = 0; i < s.size(); ++i) {
                if (--map[s[i]] >= 0) ++cnt;
                while(cnt == t.size()) {
                    if (maxlen > i - left + 1) {
                        maxlen = i - left + 1;
                        start = left;
                    } 
                    if (++map[s[left]] > 0) cnt--;
                    left++;
                }
            }
            return maxlen == s.size() + 1 ? "" : s.substr(start, maxlen);
        }
    };
  • 相关阅读:
    Flask-SQLAlchemy
    with 与 上下文管理器
    使用@property
    C++:如何把一个int转成4个字节?
    尝试理解Flask源码 之 搞懂WSGI协议
    qt setData()和data()
    我使用过的Linux命令之sftp
    linux下如何使用sftp命令
    Linux环境下安装JDK
    CentOS 6.5 配置IP地址的三种方法
  • 原文地址:https://www.cnblogs.com/lau1997/p/12805741.html
Copyright © 2020-2023  润新知