lintcode624- Remove Substrings- medium
Given a string s
and a set of n
substrings. You are supposed to remove every instance of those n substrings from s so that s is of the minimum length and output this minimum length.
Example
Given s = ccdaabcdbb
, substrs = ["ab", "cd"]
Return 2
Explanation: ccdaabcdbb
-> ccdacdbb
-> cabb
-> cb
(length = 2)
BFS。queue+set。尝试把各个词典词从原单词消去,切记每消去一个单词都要记录下来新单词,再去递归的感觉(BFS实现)试删单词。1.试着删不同类型的单词 2.试着在不同的位置删同一种单词。所以流程是 1.从queue里掏出来 2.for循环每种单词删删看 3.while循环当前种类单词在不同的位置删删看 4.内部每次删了以后打个擂台,加加进queue。
主要是要认识到这个问题的复杂性。不是简单地遍历去掉就行了,像消消乐一样,不同的消去顺序最后得到的结果是不一样的。可能先消了某个关键的字符会阻碍你后续尽可能消更多。比如ccdaabcdbb可以用'ab','bc','cd'消。1.先消cd -ccdaadbb-caadbb 不能继续消了。2.先消ab -ccdacdbb-cacdbb-cabb-cb 不能继续消了。你可以看到,如果你先消了cd是会阻碍后续进程的。所以,你需要每次消去某个东西,做出影响后,都要把产生的结果记录下来,之后继续对这个潜力股进行试验,不能漏过任何一种可能。这让你想到什么,当然是BFS了!!!
细节:1.查substring有现成方法。s.indexOf(substring),会返回第一个idx, 还有一个多态s.indexOf(substring, startIdx),会从startIdx开始找sub 2.HashSet还是可以用在string上面的,因为String的equals已经被改写过了,所以只要内容是一样的就能被set.contains检测到。
public class Solution { /* * @param s: a string * @param dict: a set of n substrings * @return: the minimum length */ public int minLength(String s, Set<String> dict) { // write your code here if (s == null) { return 0; } Queue<String> queue = new LinkedList<String>(); Set<String> set = new HashSet<String>(); int minLength = Integer.MAX_VALUE; queue.offer(s); set.add(s); while (!queue.isEmpty()) { String string = queue.poll(); minLength = Math.min(minLength, string.length()); for (String sub : dict) { int index = string.indexOf(sub); while (index != -1) { String newStr = string.substring(0, index) + string.substring(index + sub.length(), string.length()); //每删去一个单词都要以后尝试这种可能 if (!set.contains(newStr)) { queue.offer(newStr); set.add(newStr); } // 每一个可以删去的单词也要在每一个位置都删单独个试试 index = string.indexOf(sub, index + 1); } } } return minLength; } }