Template : Two Pointers & Hash -> String process
Reference : https://leetcode.com/discuss/72701/here-10-line-template-that-can-solve-most-substring-problems
/* For most substring problem, we are given a string and need to find a substring of it which satisfy some restrictions. A general way is to use a hashmap assisted with two pointers. */ int findSubstring(string s){ int[] map = new int[256]; int counter; // check whether the substring is valid int begin=0, end=0; //two pointers, one point to tail and one head int d; //the length of substring for() { /* initialize the hash map here */ } while(end<s.size()){ if(map[s[end++]]-- ?){ /* modify counter here */ } while(/* counter condition */){ /* update d here if finding minimum*/ //increase begin to make it invalid/valid again if(map[s[begin++]]++ ?){ /*modify counter here*/ } } /* update d here if finding maximum*/ } return d; }
3. Longest Substring Without Repeating Characters
Given a string, find the length of the longest substring without repeating characters.
Examples:
Given "abcabcbb"
, the answer is "abc"
, which the length is 3.
Given "bbbbb"
, the answer is "b"
, with the length of 1.
Given "pwwkew"
, the answer is "wke"
, with the length of 3. Note that the answer must be a substring, "pwke"
is a subsequence and not a substring.
1 public class Solution { 2 public int lengthOfLongestSubstring(String s) { 3 int[] map = new int[256]; 4 5 int begin = 0, end = 0; 6 int count = 0, max = 0; 7 while (end < s.length()) { 8 if (map[s.charAt(end++)]++ > 0) count++; 9 while (count > 0) if (map[s.charAt(begin++)]-- > 1) count--; 10 max = max > (end - begin) ? max : (end - begin); 11 } 12 13 return max; 14 } 15 }
159. Longest Substring with At Most Two Distinct Characters
Given a string, find the length of the longest substring T that contains at most 2 distinct characters.
For example, Given s = “eceba”
,
T is "ece" which its length is 3.
public class Solution { public int lengthOfLongestSubstringTwoDistinct(String s) { if (s == null || s.isEmpty()) return 0; if (s.length() <= 2) return s.length(); int[] map = new int[256]; int begin = 0, end = 0; // two pointers int count = 0, max = 0; while (end < s.length()) { if (map[s.charAt(end++)]++ == 0) count++; // new diff character while (count > 2) if (map[s.charAt(begin++)]-- == 1) count--; max = max > (end - begin) ? max : (end - begin); } return max; } }
340. Longest Substring with At Most K Distinct Characters
Given a string, find the length of the longest substring T that contains at most k distinct characters.
For example, Given s = “eceba”
and k = 2,
T is "ece" which its length is 3.
1 public class Solution { 2 public int lengthOfLongestSubstringKDistinct(String s, int k) { 3 if (k == 0 || s == null || s.isEmpty()) return 0; 4 if (s.length() <= k) return s.length(); 5 6 int[] map = new int[256]; 7 int begin = 0, end = 0; 8 int count = 0, max = 0; 9 10 while (end < s.length()) { 11 if (map[s.charAt(end++)]++ == 0) count++; 12 while (count > k) if (map[s.charAt(begin++)]-- == 1) count--; 13 max = max > (end - begin) ? max : (end - begin); 14 } 15 16 return max; 17 } 18 }
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.
1 public class Solution { 2 public String minWindow(String s, String t) { 3 if (s == null || s.isEmpty() || t == null || t.isEmpty()) return ""; 4 int[] map =new int[256]; 5 6 for (int i = 0; i < t.length(); i++) { 7 map[t.charAt(i)]++; 8 } 9 10 int begin = 0, head = 0, end = 0; 11 int min = Integer.MAX_VALUE; 12 int count = t.length(); 13 14 while (end < s.length()) { 15 if (map[s.charAt(end++)]-- > 0) count--; 16 while (count == 0) { 17 min = min > end - begin ? (end - (head = begin)) : min; 18 if (map[s.charAt(begin++)]++ >= 0) count++; 19 } 20 } 21 22 return min == Integer.MAX_VALUE ? "" : s.substring(head, head + min); 23 } 24 }