[LintCode] 最小子串覆盖 Java
Posted BrookLearnData
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[LintCode] 最小子串覆盖 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往前走一位。寻找下一个子串。
代码:
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 int[] srcHash = new int[255]; //记录目标字符串每个字母出现次数 for(int i=0;i<target.length();i++){ srcHash[target.charAt(i)]++; } int start =0,i=0; int[] destHash = new int[255]; //记录串口内每个字母出现的次数 int found = 0; int begin = -1,end = source.length(),minLength = source.length(); for(start = i=0;i<source.length();i++){ destHash[source.charAt(i)]++; //没来一个字符给他出现次数加1 //如果加1后,这个字符的数量不超过目标串中该字符数量,则找到了一个匹配字符 if(destHash[source.charAt(i)] <= srcHash[source.charAt(i)]) found++; // 如果找到的匹配字符数等于目标串长度,说明找到了一个符合要求的子串 if(found == target.length()){ // 将开头没用的都跳过,没用是指该字符出现次数超过了目标串中出现的次数,并把它们出现次数都减1 while(start < i && destHash[source.charAt(start)] > srcHash[source.charAt(start)]){ destHash[source.charAt(start)]--; start++; } // 这时候start指向该子串开头的字母,判断该子串长度 if(i - start < minLength){ minLength = i - start; begin = start; end = i; } // 把开头的这个匹配字符跳过,并将匹配字符数减1 destHash[source.charAt(start)]--; found--; // 子串起始位置加1,我们开始看下一个子串了 start++; } } return begin == -1 ? "" : source.substring(begin,end + 1); } }
以上是关于[LintCode] 最小子串覆盖 Java的主要内容,如果未能解决你的问题,请参考以下文章
最小子串覆盖 · Minimum Window Substring
Leetcode53.最大子串和(简单)76.最小子串覆盖(困难)3. 最长子串不重复问题(中等)
Leetcode53.最大子串和(简单)76.最小子串覆盖(困难)3. 最长子串不重复问题(中等)