Leetcode 76. Minimum Window Substring
来源:互联网 发布:天津seo网络推广 编辑:程序博客网 时间:2024/05/20 18:17
76. Minimum Window Substring
Given a string S and a string T, find the minimum window in S which will contain all the characters in T in complexity O(n).
For example,
S = "ADOBECODEBANC"
T = "ABC"
Minimum window is "BANC"
.
Note:
If there is no such window in S that covers all characters in T, return the empty string ""
.
If there are multiple such windows, you are guaranteed that there will always be only one unique minimum window in S.
解法一:
暴力解。从左到右,寻找一个窗口满足包括T。
解法二:
先用HashMap统计t中各个元素和出现的频率。然后从左到右,先将窗口扩到刚好包括T中所有元素,时候相当于右边固定,然后缩小左边。如果左边所指元素在T中没有出现,或者是出现之后当前子串包含的个数大于T中的频率(冗余),也可以缩。当刚好无法再缩小时,计算长度,更新结果。
自己用了两个map,一个是t的统计,另外一个是temp,用于统计当前子串。debug了俩小时,结论是:越是繁琐的代码,越不要复制粘贴,要不然眼花缭乱,找错都要找半天!!
count变量用于统计当前有效字符数,当count==t.length()说明已经找到了满足要求的子串;外层for循环中的变量i其实就是窗口的右指针,所以只要维护一个left指针就可以了,初始位于0的位置。当计算完length之后,left++,移动到下一个子串开始的合法位置。
public class Solution { // 67ms public String minWindow(String s, String t) { Map<Character, Integer> tmap = new HashMap<Character, Integer>(); Map<Character, Integer> cmap = new HashMap<Character, Integer>(); for(int i=0; i<t.length(); i++){ // 先统计t中的元素,放入tmap if(tmap.get(t.charAt(i))==null) tmap.put(t.charAt(i), 1); else tmap.put(t.charAt(i), tmap.get(t.charAt(i))+1); } int left = 0, length = Integer.MAX_VALUE, resStart = -1, count = 0; for(int i=0; i<s.length(); i++){ if(tmap.get(s.charAt(i))!=null){ // 如果该字符在t中出现 if(cmap.get(s.charAt(i))==null){ // cmap中没有,则计数 cmap.put(s.charAt(i), 1); count++; }else if(cmap.get(s.charAt(i)) < tmap.get(s.charAt(i))){ // cmap中有但数量不够,计数 count++; cmap.put(s.charAt(i), cmap.get(s.charAt(i))+1); }else{ // 多余的目标字符,放入,但不计入有效数目 cmap.put(s.charAt(i), cmap.get(s.charAt(i))+1); } } if(count==t.length()){ // 当收集够了目标字符 while(true){ if(tmap.get(s.charAt(left))==null){ // 无关字符,左移指针 left++; }else if(cmap.get(s.charAt(left)) > tmap.get(s.charAt(left))){ //多余字符,左移指针 cmap.put(s.charAt(left), cmap.get(s.charAt(left))-1); left++; }else{ // 已经到了不能删的位置。 int curlength = i - left + 1; if(length > curlength){ resStart = left; length = curlength; } cmap.put(s.charAt(left), cmap.get(s.charAt(left))-1); left++; count--; break; } } } } return resStart==-1 ? "" : s.substring(resStart, resStart + length); }}
优化:使用俩int[256]数组替代hashmap。
public class Solution { // 7ms public String minWindow(String s, String t) { int[] tar = new int[256]; int[] temp = new int[256]; for(int i=0; i<t.length(); i++){ tar[t.charAt(i)]++; } int left=0, length=Integer.MAX_VALUE, start=-1, count=0; char cur; for(int i=0; i<s.length(); i++){ cur = s.charAt(i); if(tar[cur]!=0){ if(temp[cur]<tar[cur]){ temp[cur]++; count++; }else{ temp[cur]++; } } if(count==t.length()){ while(true){ cur = s.charAt(left); if(tar[cur]==0){ left++; }else if(tar[cur]<temp[cur]){ temp[cur]--; left++; }else{ int curlength = i - left + 1; if(length>curlength){ start = left; length = curlength; } temp[cur]--; left++; count--; break; } } } } return start==-1 ? "" : s.substring(start, start + length); }}
附上一开始参考的地址和其代码:
public class Solution { // 11ms public String minWindow(String S, String T) { int[] srcHash = new int[255]; // 记录目标字符串每个字母出现次数 for(int i = 0; i < T.length(); i++){ srcHash[T.charAt(i)]++; } int start = 0,i= 0; // 用于记录窗口内每个字母出现次数 int[] destHash = new int[255]; int found = 0; int begin = -1, end = S.length(), minLength = S.length(); for(start = 0, i = 0; i < S.length(); i++){ // 每来一个字符给它的出现次数加1 destHash[S.charAt(i)]++; // 如果加1后这个字符的数量不超过目标串中该字符的数量,则找到了一个匹配字符 if(destHash[S.charAt(i)] <= srcHash[S.charAt(i)]) found++; // 如果找到的匹配字符数等于目标串长度,说明找到了一个符合要求的子串 if(found == T.length()){ // 将开头没用的都跳过,没用是指该字符出现次数超过了目标串中出现的次数,并把它们出现次数都减1 while(start < i && destHash[S.charAt(start)] > srcHash[S.charAt(start)]){ destHash[S.charAt(start)]--; start++; } // 这时候start指向该子串开头的字母,判断该子串长度 if(i - start < minLength){ minLength = i - start; begin = start; end = i; } // 把开头的这个匹配字符跳过,并将匹配字符数减1 destHash[S.charAt(start)]--; found--; // 子串起始位置加1,我们开始看下一个子串了 start++; } } // 如果begin没有修改过,返回空 return begin == -1 ? "" : S.substring(begin,end + 1); }}
- LeetCode 76. Minimum Window Substring
- [LeetCode]76.Minimum Window Substring
- LeetCode 76.Minimum Window Substring
- LeetCode --- 76. Minimum Window Substring
- [Leetcode] 76. Minimum Window Substring
- [leetcode] 76.Minimum Window Substring
- **LeetCode 76. Minimum Window Substring
- leetcode 76. Minimum Window Substring
- 【LeetCode】76. Minimum Window Substring
- LeetCode 76. Minimum Window Substring
- Leetcode 76. Minimum Window Substring
- leetcode.76. Minimum Window Substring
- LeetCode 76. Minimum Window Substring
- [LeetCode] 76. Minimum Window Substring
- leetcode 76.Minimum Window Substring
- leetcode 76. Minimum Window Substring
- 76. Minimum Window Substring, leetcode
- leetcode-76. Minimum Window Substring
- 安卓系统的启动流程(源码分析)
- 二分查找
- 【iOS】配置和使用静态库
- UI设计——磨皮
- 一起talk C栗子吧( 第一百五十回:C语言实例--socket通信接口二)
- Leetcode 76. Minimum Window Substring
- LINUX SHELL控制结构
- 设计师和程序员-拓展知识关系网
- java读写文件,读超大文件
- Java千百问_06数据结构(017)_什么是二维数组
- MSSQL之四 简单查询
- 学习Asp.Net 记录1
- 从JDK源码角度看线程池原理
- c++ stl lower_bound upper_bound用法浅析