[LeetCode ] 76. Minimum Window Substring Java

题目:

给定一个字符串source和一个目标字符串target,在字符串source中找到包括所有目标字符串字母的子串。

 注意事项

如果在source中没有这样的子串,返回"",如果有多个这样的子串,返回起始位置最小的子串。

说明

在答案的子串中的字母在目标字符串中是否需要具有相同的顺序?

——不需要。

样例

给出source = "ADOBECODEBANC",target = "ABC" 满足要求的解  "BANC"

要求时间复杂度为O(n)

分析:采用哈希的思想,记录字母出现次数。
大小写字母的ASCII码不大于256,这样array['A']=3指A出现3次,array['B']=1指B出现了一次,以此类推,不能用常规意义上的定义array[0]=3表示A出现3次,这样就多了一层映射!故而数组的长度设置为256即可存放所有的字母。
首先预处理target,用256大小的整数数组tHash存储里面每个char出现的个数;
然后给定两个指标beg和end,一个移动start,也用一个256长的整数数组sHash记录从beg到end的这段字符串里面每个char出现的个数。如果sHash大于等于tHash,也就是说sHash里的每一位大于等于tHash里相应位置的值,找到当前start位置,为符合要求子串的起点,记录当前beg和end的长度,如果比已经记录的小,那么我们就选这个位最小窗口。记录beg和end。然后让start往前走一位。寻找下一个子串。 这里使用数组是取巧,也可以使用hashMap来记录,方法类似。

代码:

public class Solution {
    /*
     * @param source : A string
     * @param target: A string
     * @return: A string denote the minimum window, return "" if there is no such a string
     */
    public String minWindow(String source , String target) {
        // write your code here
        // write your code here
         // write your code here
        int[] srcHash = new int[255];
        //记录目标字符串每个字母出现次数
        for(int i=0;i<target.length();i++){
            srcHash[target.charAt(i)]++;
        }
        int start = 0,i=0,found =0;
        int[] dectHash = new int[255];

        int begin = -1,end = source.length(),minLength = source.length();
        for(start = i=0;i<source.length();i++){
            dectHash[source.charAt(i)] ++;
            if(dectHash[source.charAt(i)]<=srcHash[source.charAt(i)]) found++;       //若没有到数,添加1

            if(found == target.length()){       //找到了能包含target的字符串,然后去掉前面的无用字符串
                while(start < i && dectHash[source.charAt(start)]>srcHash[source.charAt(start)]){
                    dectHash[source.charAt(start)]--;
                    start++;
                }
                // 这时候start指向该子串开头的字母,判断该子串长度
                if(i-start < minLength){
                    minLength = i-start;
                    begin = start;
                    end = i;
                }
                //从下一个字符串开始查找
                dectHash[source.charAt(start)]--;
                found--;
                start++;
            }
        }
        return begin==-1?"":source.substring(begin,end+1);
    }
}

 

 

 

posted @ 2017-11-13 11:15  荒野第一快递员  阅读(402)  评论(0编辑  收藏  举报