美文网首页
LeetCode Minimum Window Substrin

LeetCode Minimum Window Substrin

作者: Bluwil | 来源:发表于2018-08-21 10:06 被阅读0次

最短子字符串问题

问题描述

给定一个字符串S,和一个字符串T,在字符串S中找出最短的包含T中所有字符的子字符串。如果找不到则返回空字符串
示列:

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

解题思路

对于求子字符串的问题,我们通常可以使用两个指针left和right(初始指向0)来顺序寻找满足条件的子字符串。示列中right依次遍历ADOBEC则满足包含字符ABC,记录此时[left,right]子字符串长度。left右移一位,right继续遍历使得[left,right]包含字符ABC,重复操作直到遍历完成,然后通过记录得出最短子字符串。
附上本人代码,使用HashMap来维护判断是否包含T中的字符。由于每次需要遍历一遍HashMap效率比较低。

public class Solution2 {
    public String minWindow(String s, String t) {
        if (s == null || t == null || s.length() < t.length()) return "";
        HashMap<Character, Integer> map = new HashMap<>();
        for (int i = 0; i < t.length(); i++) {
            map.put(t.charAt(i), 0);
        }
        int n = s.length();
        int right = 0;
        int lo = 0, ro = 0;
        int minLen = n;
        for (int i = 0; i < n; i++) {
            while (!match(map)) {
                char c1 = s.charAt(right);
                if (map.containsKey(c1)) {
                    map.replace(c1, 1);
                }
                right++;
            }
            if (match(map) && minLen > right - i) {
                minLen = right - i;
                lo = i;
                ro = right;
            }
            char c = s.charAt(i);
            if (map.containsKey(c)) {
                map.replace(c, 0);
            }
        }
        return ro - lo > 0 ? s.substring(lo, ro) : "";
    }

    private boolean match(HashMap<Character, Integer> map) {
        for (Map.Entry<Character, Integer> entry : map.entrySet()) {
            if (entry.getValue() == 0) {
                return false;
            }
        }
        return true;
    }
}

附上大神给出的代码,通过int[] map = new int[128]来判定是否包含字符效率高。思路:字符A 对应ASCII码数字为65。用map[65]++,map[65]--来标记字符A

class Solution {
    public String minWindow(String s, String t) {
        if (s == null || t == null || s.length() < t.length()) return "";
        int[] map = new int[128];
        for (char c : t.toCharArray()) {
            map[c]++;
        }
        int m = s.length(), n = t.length();
        int minLen = m + 1, left = 0;
        int lo = 0, cnt = 0;
        for (int hi = 0; hi < m; hi++) {
            char c = s.charAt(hi);
            map[c]--;
            if (map[c] >= 0) cnt++;
            while (cnt == n) {
                if (minLen > hi - lo + 1) {
                    minLen = hi - lo + 1;
                    left = lo;
                }
                char pre = s.charAt(lo);
                map[pre]++;
                if (map[pre] > 0) cnt--;
                lo++;
            }
        }
        return minLen == m + 1 ? "" : s.substring(left, left + minLen);
    }
}

存在的问题

编码问题,int[] map = new int[128]表示的是英文的128个字符。如果是中文(占2-3个字节)需要扩充数组长度。

相关文章

网友评论

      本文标题:LeetCode Minimum Window Substrin

      本文链接:https://www.haomeiwen.com/subject/pphdiftx.html