subject
Give you a string S and a string t, please find out in the string S: the smallest string containing all the characters of T.
Link: https://leetcode-cn.com/problems/minimum-window-substring
Problem solving record
- Construct a window with two pointers
- First left pointer to last matching character as start point
- Move the right pointer to the right to record the matching characters. When the number of matching characters meets the requirements, compare the size record position
- Now move the left pointer to the matching character that matches the matching number
- Move the right pointer again, meet the requirements, and record until the right pointer is out of range
/** * @author ffzs * @describe * @date 2020/5/23 */ public class Solution { public String minWindow(String s, String t) { char[] scl = s.toCharArray(), tcl = t.toCharArray(); int[] ori = new int[128]; for (char tc: tcl) ori[tc]++; int[] count = new int[128]; int left=-1, right=0, min=Integer.MAX_VALUE; int[] res = new int[2]; while (right < s.length()) { if (check(tcl, scl[right])) { if(left==-1) left=right; count[scl[right]]++; if (check(ori, count, tcl)) { if(min > right-left) { min = right - left; res[0] = left; res[1] = right+1; } count[scl[left]]--; left++; while (left<=right) { if(check(tcl, scl[left])) { if(check(ori, count, tcl)) { if(min > right-left) { min = right - left; res[0] = left; res[1] = right+1; } count[scl[left]]--; }else{ break; } } left++; } } } right++; } return s.substring(res[0], res[1]); } private boolean check (char[] tcl, char s) { for (char t: tcl) { if (t==s) return true; } return false; } private boolean check (int[] ori, int[] count, char[] tcl) { for(char tc: tcl) { if (count[tc]<ori[tc]) return false; } return true; } } class test { public static void main(String[] args) { Solution sl = new Solution(); String s = "cabefgecdaecf"; String t = "cae"; System.out.println(sl.minWindow(s, t)); } }
optimization
It's written poorly and barely passed. It analyzes the following problems. It's mainly because the two check parts take time. After thinking, there are two optimizations:
- For conformity, it can be recorded according to the quantity passed. If the right character conforms to the requirement, the quantity will be reduced by one until the quantity is 0, indicating the matching
- You can operate directly on ori. If it is greater than 0, you need to match characters, which can reduce many logical judgments
- Because it is the most solvable, it is not necessary to optimize to the most probable situation when judging the size of each time, which is simpler in logic
/** * @author ffzs * @describe * @date 2020/5/23 */ public class Solution { public String minWindow(String s, String t) { char[] scr = s.toCharArray(), tcr = t.toCharArray(); int min = scr.length + 1, left = 0, right = 0, res = 0, count = tcr.length; int[] ori = new int[128]; for (char c : tcr) ori[c]++; while (right < scr.length) { if (ori[scr[right]] > 0) { count--; } ori[scr[right]]--; right++; while (count == 0) { ori[scr[left]]++; if (ori[scr[left]] > 0) { if (right - left < min) { min = right - left; res = left; } count++; } left++; } } return min==scr.length+1? "" : s.substring(res, res + min); } } class test { public static void main(String[] args) { Solution sl = new Solution(); String s = "aancc"; String t = "ca"; System.out.println(sl.minWindow(s, t)); } }