// O(n^2) solution public static int checkAns(ArrayList<String> A, ArrayList<String> Q) { HashSet<String> dict = new HashSet<String>(); for (String s : Q) { dict.add(s); } Pair<Integer, Integer> ans = new Pair<Integer, Integer>(0, A.size() - 1); for (int l = 0; l < A.size(); ++l) { HashMap<String, Integer> count = new HashMap<String, Integer>(); for (int r = l; r < A.size() && r - l < ans.getSecond() - ans.getFirst(); ++r) { if (dict.contains(A.get(r))) { count.put(A.get(r), count.containsKey(A.get(r)) ? count.get(A.get(r)) + 1 : 1); } if (count.size() == Q.size()) { if (r - l < ans.getSecond() - ans.getFirst()) { ans.setFirst(l); ans.setSecond(r); } break; } } count.clear(); } return ans.getSecond() - ans.getFirst(); }
// @include public static Pair<Integer, Integer> findSmallestSubarrayCoveringSubset( ArrayList<String> A, ArrayList<String> Q) { HashSet<String> dict = new HashSet<String>(Q); HashMap<String, Integer> countQ = new HashMap<String, Integer>(); int l = 0, r = 0; Pair<Integer, Integer> res = new Pair<Integer, Integer>(-1, -1); while (r < A.size()) { // Keep moving r until it reaches end or countQ has |Q| items. while (r < A.size() && countQ.size() < Q.size()) { if (dict.contains(A.get(r))) { countQ.put(A.get(r), countQ.containsKey(A.get(r)) ? countQ.get(A.get(r)) + 1 : 1); } ++r; } if (countQ.size() == Q.size() && // found |Q| keywords. ((res.getFirst() == -1 && res.getSecond() == -1) || r - 1 - l < res.getSecond() - res.getFirst())) { res.setFirst(l); res.setSecond(r - 1); } // Keep moving l until it reaches end or countQ has less |Q| items. while (l < r && countQ.size() == Q.size()) { if (dict.contains(A.get(l))) { int it = countQ.get(A.get(l)); countQ.put(A.get(l), --it); if (it == 0) { countQ.remove(A.get(l)); if ((res.getFirst() == -1 && res.getSecond() == -1) || r - 1 - l < res.getSecond() - res.getFirst()) { res.setFirst(l); res.setSecond(r - 1); } } } ++l; } } return res; }