/** * Given a string s and a list of strings dict, you need to add a closed pair * of bold tag and to wrap the substrings in s that exist in dict. If * two such substrings overlap, you need to wrap them together by only one pair * of closed bold tag. Also, if two substrings wrapped by bold tags are * consecutive, you need to combine them. * * Example 1: * * Input: * s = "abcxyz123" * dict = ["abc","123"] * Output: * "abcxyz123" * * Example 2: * Input: * s = "aaabbcc" * dict = ["aaa","aab","bc"] * Output: * "aaabbcc" * * Note: * The given dict won't contain duplicates, and its length won't exceed 100. * All the strings in input have length in range [1, 1000]. */ public class AddBoldTagInString616 { public String addBoldTag(String s, String[] dict) { Trie trie = constructTrie(dict); StringBuilder sb = new StringBuilder(); int l = 0; int r = 0; char[] chars = s.toCharArray(); for (int i=0; i= r) { if (r > l) { sb.append(""); sb.append(s.substring(l, r)); sb.append(""); } r = i + 1; l = r; sb.append(s.charAt(i)); } } else { r = Math.max(r, i+len); } } if (r > l) { sb.append(""); sb.append(s.substring(l, r)); sb.append(""); } return sb.toString(); } private Trie constructTrie(String[] dict) { Trie res = new Trie(); for (String word: dict) { res.addWord(word); } return res; } public String addBoldTag2(String s, String[] dict) { StringBuilder sb = new StringBuilder(); int l = 0; int r = 0; for (int i=0; i len) { len = word.length(); } } if (len == 0) { if (i >= r) { if (r > l) { sb.append(""); sb.append(s.substring(l, r)); sb.append(""); } r = i + 1; l = r; sb.append(s.charAt(i)); } } else { r = Math.max(r, i+len); } } if (r > l) { sb.append(""); sb.append(s.substring(l, r)); sb.append(""); } return sb.toString(); } /** * https://leetcode.com/problems/add-bold-tag-in-string/discuss/104262/short-java-solution */ public String addBoldTag3(String s, String[] dict) { int n = s.length(); int[] mark = new int[n+1]; for(String d : dict) { int i = -1; while((i = s.indexOf(d, i+1)) >= 0) { mark[i]++; mark[i + d.length()]--; } } StringBuilder sb = new StringBuilder(); int sum = 0; for(int i = 0; i <= n; i++) { int cur = sum + mark[i]; if (cur > 0 && sum == 0) sb.append(""); if (cur == 0 && sum > 0) sb.append(""); if (i == n) break; sb.append(s.charAt(i)); sum = cur; } return sb.toString(); } /** * https://leetcode.com/problems/add-bold-tag-in-string/discuss/104263/Java-solution-Same-as-Merge-Interval. */ public String addBoldTag4(String s, String[] dict) { List intervals = new ArrayList<>(); for (String str : dict) { int index = -1; index = s.indexOf(str, index); while (index != -1) { intervals.add(new Interval(index, index + str.length())); index +=1; index = s.indexOf(str, index); } } intervals = merge(intervals); int prev = 0; StringBuilder sb = new StringBuilder(); for (Interval interval : intervals) { sb.append(s.substring(prev, interval.start)); sb.append(""); sb.append(s.substring(interval.start, interval.end)); sb.append(""); prev = interval.end; } if (prev < s.length()) { sb.append(s.substring(prev)); } return sb.toString(); } class Interval { int start, end; public Interval(int s, int e) { start = s; end = e; } public String toString() { return "[" + start + ", " + end + "]" ; } } public List merge(List intervals) { if (intervals == null || intervals.size() <= 1) { return intervals; } Collections.sort(intervals, new Comparator(){ public int compare(Interval a, Interval b) { return a.start - b.start; } }); int start = intervals.get(0).start; int end = intervals.get(0).end; List res = new ArrayList<>(); for (Interval i : intervals) { if (i.start <= end) { end = Math.max(end, i.end); } else { res.add(new Interval(start, end)); start = i.start; end = i.end; } } res.add(new Interval(start, end)); return res; } /** * https://leetcode.com/problems/add-bold-tag-in-string/discuss/104262/short-java-solution */ public String addBoldTag5(String s, String[] dict) { int n = s.length(); int[] mark = new int[n+1]; for(String d : dict) { int i = -1; while((i = s.indexOf(d, i+1)) >= 0) { mark[i]++; mark[i + d.length()]--; } } StringBuilder sb = new StringBuilder(); int sum = 0; for(int i = 0; i <= n; i++) { int cur = sum + mark[i]; if (cur > 0 && sum == 0) sb.append(""); if (cur == 0 && sum > 0) sb.append(""); if (i == n) break; sb.append(s.charAt(i)); sum = cur; } return sb.toString(); } public String addBoldTag6(String s, String[] dict) { if (s == null || s.length() == 0) return s; StringBuilder sb = new StringBuilder(); int l = 0; int r = 0; int len = s.length(); for (int i=0; i").append(s.substring(l, r)).append(""); } sb.append(s.charAt(i)); l = i+1; r = i+1; } if (l != r) { sb.append("").append(s.substring(l, r)).append(""); } return sb.toString(); } } class Trie { Map children = new HashMap<>(); boolean end = false; public void addWord(String word) { addWord(word.toCharArray(), 0); } public void addWord(char[] chars, int i) { if (i == chars.length) { end = true; return; } char c = chars[i]; if (children.containsKey(c)) { children.get(c).addWord(chars, i+1); } else { Trie child = new Trie(); children.put(c, child); child.addWord(chars, i+1); } } public int search(char[] chars, int i) { return search(chars, i, i, 0); } private int search(char[] chars, int i, int x, int len) { if (x >= chars.length) return end ? x-i : len; char c = chars[x]; if (!children.containsKey(c)) return end ? x-i : len; return children.get(c).search(chars, i, x+1, len); } // public void print() { // for (char c: children.keySet()) { // System.out.println(c); // children.get(c).print(); // } // } }