常见算法技巧之——双指针思想 (4)

维护一个needs数组,保存T字符串每个字符出现的次数,再维护一个window数组,保存当前窗口中各个字符的数量,后面可以根据这两个数组判断当前窗口是否包含了字符串T

使用一个count变量,如果当前字符属于T,而且窗口中还没有足够多的这个字符就说明这个字符目前对于窗口来说是必要的,那么把这个字符加入窗口后给count++,如果窗口中已经有了足够的这个字符,那将其加入窗口后无需给count++。而当将一个字符移出窗口时,如果移出了这个字符,窗口不再包含T的所有字符,就说明这个字符目前对于窗口来说也是必要的,那移出后给count--,如果不是必需的则不需要减小count。这样维护下来的一个count可以指示当前窗口是否完整包含了字符串T,如果count的大小等于T的长度就说明此时的窗口完整的包含了T,这样就可以快速判断窗口是否包含T,节省了程序执行时间。

//给出的示例题解中用curr代替了window,curr记为current,表示当前的窗口 class Solution { public String minWindow(String s, String t) { if (s == null || s == "" || t == null || t == "" || s.length() < t.length()) { return ""; } int l = 0, r = 0; //定义左右指针 int size = Integer.MAX_VALUE; //窗口大小 int ans_l = 0; //最优情况下左边的指针 int count = 0; //下面needs和curr的下标是字符的ASCII码值 int[] needs = new int[255]; //需要的 int[] curr = new int[255]; //现有的 for (int i = 0; i < t.length(); i++) { //初始化needs needs[t.charAt(i)]++; } while (r < s.length()) { char c = s.charAt(r); //当前右指针指的字符 if (needs[c] != 0) { //需要这个字符 if (curr[c] < needs[c]) { //这个字符对于目前窗口是必需的 count++; } curr[c]++; } r++; while (count == t.length() && l < r) { if (size > r-l) { ans_l = l; size = r-l; } char c1 = s.charAt(l); if (needs[c1] > 0) { if (curr[c1] == needs[c1]) { //这个字符对于目前窗口来说是必需的 count--; } curr[c1]--; } l++; } } return size==Integer.MAX_VALUE?"": s.substring(ans_l,ans_l+size); } }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zwywzf.html