查看: 2401| 回复: 1
跳转到指定楼层
上一主题 下一主题
收起左侧

[Leetcode] Subarray + sliding window类型总结

全局:

注册一亩三分地论坛,查看更多干货!

您需要 登录 才可以下载或查看附件。没有帐号?注册账号

x
本帖最后由 blue_epoch 于 2019-9-10 11:30 编辑

SubString + Sliding window 类题型
借用Map的解法

第一类:找尽量不重复的最大substring /substring个数

3. Longest Substring Without Repeating Characters
常见是Set的解法,Discussion里面有说就不写在这里了。

Map方法:一旦map中有当前char且比慢指针 i 更后面就要更新慢指针 i
代码如下:
public int lengthOfLongestSubstring(String s) {
        if (s == null || s.length() == 0) return 0;
        int result = 0;
        Map<Character, Integer> map = new HashMap<>();
        for (int i = 0, j = 0; j < s.length(); j++) {
            char c = s.charAt(j);
            if (map.containsKey(c) && map.get(c) >= i) {
                i = map.get(c);
                i++;
            }
            result = Math.max(result, j - i + 1);
            map.put(c, j);
        }
        return result;
     }


第二类:找尽量重复的最大substring/substring个数

159. Longest Substring with At Most Two Distinct Characters
340. Longest Substring with At Most K Distinct Characters
992. Subarrays with K Different Integers

这三题可以用同一个模版解,模版是340题答案,最多K个不同字符的最大subarray长度。
其中992题虽然问的是正好K个不同字符,但实际只要用(最多K个 - 最多K-1个)就可以了,也就是return 模版(A, K) - 模版(A, K - 1);这里只要改input类型。

如果是要求substring个数(992),只需要把res = Math.max(res, i - start + 1)更改为res += j - i + 1就可以了。

模版如下:
public int lengthOfLongestSubstringKDistinct(String s, int k) {        if (s == null || s.length() == 0) return 0;
        HashMap<Character, Integer> map = new HashMap<>();
        int start = 0;
        int res = 0;
        for(int i = 0; i < s.length(); i++) {
            map.put(s.charAt(i), i);
            if (map.size() > k) {
                int leftMost = s.length();
                for (int num : map.values()) {
                    leftMost = Math.min(leftMost, num);
                }
                map.remove(s.charAt(leftMost));
                start = leftMost + 1;
            } else {
                res = Math.max(res, i - start + 1);
            }
        }
        return res;
    }

每次移除尽可能短的字符,使得剩下的subarray (i 到 j) 字符数目不超过K
我觉得这种模版其实类似固定大小为K的最小堆 min priority heap, 只不过元素是map, 每次加入新元素后,如果map size大于K了,就pop出一个value最小的map.





评分

参与人数 2大米 +27 收起 理由
pikado + 25 欢迎分享你知道的情况,会给更多积分奖励!
harveyfyang + 2 给你点个赞!

查看全部评分


上一篇:刷题慢慢找到感觉了……
下一篇:超全Two Sum总结
🔗
 楼主| blue_epoch 2019-9-10 11:06:52 | 只看该作者
全局:
本帖最后由 blue_epoch 于 2019-9-10 11:15 编辑

补充:
用Array会比Map快,但需要限定是ASCII。
模版的Set方法如下:
public int lengthOfLongestSubstringKDistinct2(String s, int k) {        int[] count = new int[256];
        int res = 0, num = 0, j = 0;
        for (int i = 0; i < s.length(); i++) {
            if (count[s.charAt(i)] == 0) num++;
            count[s.charAt(i)]++;
            while (num > k) {
                count[s.charAt(j)]--;
                if (count[s.charAt(j)] == 0) num--;
                j++;
            }
            res = Math.max(res, i - j + 1);
        }
        return res;
    }

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册账号
隐私提醒:
  • ☑ 禁止发布广告,拉群,贴个人联系方式:找人请去🔗同学同事飞友,拉群请去🔗拉群结伴,广告请去🔗跳蚤市场,和 🔗租房广告|找室友
  • ☑ 论坛内容在发帖 30 分钟内可以编辑,过后则不能删帖。为防止被骚扰甚至人肉,不要公开留微信等联系方式,如有需求请以论坛私信方式发送。
  • ☑ 干货版块可免费使用 🔗超级匿名:面经(美国面经、中国面经、数科面经、PM面经),抖包袱(美国、中国)和录取汇报、定位选校版
  • ☑ 查阅全站 🔗各种匿名方法

本版积分规则

>
快速回复 返回顶部 返回列表