leetcode -- Substring with Concatenation of All Words
思路:
从左往右扫描主字符串,用两个map来统计字符串的出现次数
这里L数组中可能会出现两个相同的字符串
1 import java.util.Collection; 2 public class Solution { 3 public ArrayList<Integer> findSubstring(String S, String[] L) { 4 ArrayList<Integer> results = new ArrayList<Integer>(); 5 int len = L.length; 6 if (len == 0) { 7 results.add(0); 8 return results; 9 } 10 11 int M = S.length(); 12 int N = L[0].length(); 13 Map<String, Integer> expected = new HashMap<String, Integer>(); 14 Map<String, Integer> real = new HashMap<String, Integer>(); 15 for (int j = 0; j < len; j++) { 16 if(expected.get(L[j]) == null){ 17 expected.put(L[j], 1); 18 real.put(L[j], 0); 19 } else{ 20 expected.put(L[j], expected.get(L[j]) + 1); 21 } 22 } 23 24 for (int i = 0; i <= (M - N * len);) { 25 int j = i; 26 for (; j < i + N * len;) { 27 String tmp = S.substring(j, j + N); 28 if(expected.get(tmp) == null){ 29 i = i + 1; 30 for (int m = 0; m < len; m++) { 31 real.put(L[m], 0); 32 } 33 break; 34 }else { 35 real.put(tmp, real.get(tmp) + 1); 36 j = j + N; 37 } 38 } 39 40 if (j >= i + N * len) { 41 boolean flag = true; 42 for(int n = 0; n < L.length; n++){ 43 if(expected.get(L[n]) != real.get(L[n])){ 44 flag = false; 45 break; 46 } 47 } 48 49 if(flag){ 50 results.add(i); 51 i = i + N; 52 } else { 53 i = i + 1; 54 } 55 56 for (int m = 0; m < len; m++) { 57 real.put(L[m], 0); 58 } 59 } 60 } 61 return results; 62 } 63 }
重构后代码:
1 public static ArrayList<Integer> findSubstring3(String S, String[] L) { 2 ArrayList<Integer> results = new ArrayList<Integer>(); 3 int len = L.length; 4 if (len == 0) { 5 results.add(0); 6 return results; 7 } 8 9 int M = S.length(); 10 int N = L[0].length(); 11 Map<String, Integer> expected = new HashMap<String, Integer>(); 12 Map<String, Integer> real = new HashMap<String, Integer>(); 13 for (int j = 0; j < len; j++) { 14 if (expected.get(L[j]) == null) { 15 expected.put(L[j], 1); 16 real.put(L[j], 0); 17 } else { 18 expected.put(L[j], expected.get(L[j]) + 1); 19 } 20 } 21 22 for (int i = 0; i <= (M - N * len); i++) { 23 int j = 0; 24 for (; j < len;) { 25 String tmp = S.substring(i + j * N, i + (j + 1) * N); 26 if (expected.get(tmp) == null) { 27 break; 28 } else { 29 real.put(tmp, real.get(tmp) + 1); 30 if (real.get(tmp) > expected.get(tmp)) { 31 break; 32 } 33 j = j + 1; 34 } 35 } 36 37 if (j == len) { 38 results.add(i); 39 } 40 for (int m = 0; m < len; m++) { 41 real.put(L[m], 0); 42 } 43 44 } 45 return results; 46 }
易错的几个数据集:
String S = "lingmindraboofooowingdingbarrwingmonkeypoundcake";
String[] L = new String[] { "fooo", "barr", "wing", "ding", "wing" };
String S2 = "aaa";
String[] L2 = new String[] { "a", "b" };
String S3 = "barfoothefoobarman";
String[] L3 = new String[] { "foo", "bar" };