zoukankan      html  css  js  c++  java
  • 滑动窗口-Substring Search Problem

    2018-07-18 11:19:19

    一、Minimum Window Substring

    问题描述:

    问题求解:

        public String minWindow(String s, String t) {
            String res = "";
            if (t.length() > s.length()) return res;
            Map<Character, Integer> map = new HashMap<>();
            for (int i = 0; i < t.length(); i++) {
                map.put(t.charAt(i), map.getOrDefault(t.charAt(i), 0) + 1);
            } 
            int begin, end, count;
            begin = 0;
            end = 0;
            count = map.size();
            int minLen = Integer.MAX_VALUE;
            for (; end < s.length(); end++) {
                char c = s.charAt(end);
                if (map.containsKey(c)) {
                    map.put(c, map.get(c) - 1);
                    if (map.get(c) == 0) count--;
                }
                while (count == 0) {
                    if (end - begin + 1 < minLen) {
                        res = s.substring(begin, end);
                        minLen = end - begin + 1;
                    }
                    char temp = s.charAt(begin);
                    if (map.containsKey(temp)) {
                        if (map.get(temp) == 0) count++;
                        map.put(temp, map.get(temp) + 1);
                    }
                    begin++;
                }
            }
            return res;
        }
    

    二、Longest Substring Without Repeating Characters

    问题描述:

    问题求解:

        public int lengthOfLongestSubstring(String s) {
            int[] map = new int[256];
            int res = 0;
            int begin = 0;
            for (int end = 0; end < s.length(); end++) {
                char c = s.charAt(end);
                map[c]++;
                while (map[c] > 1) {
                    map[s.charAt(begin)]--;
                    begin++;
                }
                res = Math.max(res, end - begin + 1);
            }
            return res;
        }
    

    三、Substring with Concatenation of All Words

    问题描述:

    问题求解:

    本题其实是一道拓展题,这里题目中给出了所有单词的长度相同,也就意味着可以将所有的单词看作单个字母来进行处理,如果是这样的话,那么外层循环很显然就是word length了。之后通过两个Map对单词进行计数就可以进行解决。

        public List<Integer> findSubstring(String s, String[] words) {
            List<Integer> res = new ArrayList<>();
            if (s == null || s.length() == 0 || words.length == 0) return res;
            Map<String, Integer> map = new HashMap<>();
            int wl = words[0].length();
            int num = words.length;
            int n = s.length();
            if (n < num * wl) return res;
            for (int i = 0; i < num; i++)
                map.put(words[i], map.getOrDefault(words[i], 0) + 1);
            for (int i = 0; i < wl; i++) {
                int begin, end, cnt;
                Map<String, Integer> seen = new HashMap<>();
                begin = i;
                cnt = 0;
                for (end = begin; end <= n - wl; end += wl) {
                    String str = s.substring(end, end + wl);
                    // 匹配成功
                    if (map.containsKey(str)) {
                        seen.put(str, seen.getOrDefault(str, 0) + 1);
                        cnt++;
                        // 若计数个数超过map, 则需要对窗口大小进行调整
                        while (seen.get(str) > map.get(str)) {
                            String temp = s.substring(begin, begin + wl);
                            seen.put(temp, seen.get(temp) - 1);
                            begin = begin + wl;
                            cnt--;
                        }
                        // 如果所有单词都匹配完成, 则向res中添加答案,同时将窗口大小向前挪动一步
                        if (cnt == num) {
                            res.add(begin);
                            String temp = s.substring(begin, begin + wl);
                            seen.put(temp, seen.get(temp) - 1);
                            begin = begin + wl;
                            cnt--;
                        }
                    }
                    // 当前匹配失败,则begin要从下一个开始,且所有的计数都要初始化
                    else {
                        seen.clear();
                        begin = end + wl;
                        cnt = 0;
                    }
                }
            }
            return res;
        }
    

    四、Longest Substring with At Least K Repeating Characters

    问题描述:

    问题求解:

    单纯的使用滑动窗口在修改窗口大小的时候会出现难以判断的情况,可以引入uniqueNum这个变量,来表征K个不同的字母,这样就可以大大降低问题的复杂度。

        public int longestSubstring(String s, int k) {
            int res = 0;
            char[] chs = s.toCharArray();
            for (int i = 1; i <= 26; i++) {
                res = Math.max(res, helper(chs, k, i));
            }
            return res;
        }
        
        private int helper(char[] chs, int k, int uniqueNum) {
            int res = 0;
            int[] cnt = new int[256];
            int begin = 0;
            int nolessthank = 0;
            int curUnique = 0;
            for (int end = 0; end < chs.length; end++) {
                if (cnt[chs[end]] == 0) curUnique++;
                if (cnt[chs[end]] == k - 1) nolessthank++;
                cnt[chs[end]]++;
                while (curUnique > uniqueNum) {
                    if (cnt[chs[begin]] == k) nolessthank--;
                    if (cnt[chs[begin]] == 1) curUnique--;
                    cnt[chs[begin]]--;
                    begin++;
                }
                if (curUnique == uniqueNum && nolessthank == curUnique) 
                    res = Math.max(res, end - begin + 1);
            }
            return res;
        }

    五、Max Consecutive Ones III 

    问题描述:

    问题求解:

    这种问题一般要么dp,要么滑动窗口,这种敏感性要有。

    本题就是使用滑动窗口来进行解决的问题。实质上就是求解最长的substring其中至多包含k个0。

        public int longestOnes(int[] A, int K) {
            int res = 0;
            int begin = 0;
            int cnt = 0;
            for (int end = 0; end < A.length; end++) {
                if (A[end] == 0) cnt+= 1;
                while (cnt > K) {
                    if (A[begin] == 0) cnt -= 1;
                    begin++;
                }
                res = Math.max(res, end - begin + 1);
            }
            return res;
        }
    

      

  • 相关阅读:
    Animate.css 一款强大的预设css3动画库
    关于js返回上一页的实现方法
    jquery判断字符串中是否包含特定字符的方法总结
    去掉select在苹果手机上的原生样式
    html5中如何去掉input type date默认样式
    JS和jQuery中ul li遍历获取对应的下角标
    滚动一定的高度底色递增
    喵哈哈村的狼人杀大战(5)
    喵哈哈村的狼人杀大战(2)
    One Card Poker
  • 原文地址:https://www.cnblogs.com/hyserendipity/p/9328195.html
Copyright © 2011-2022 走看看