Given a set of keywords
words
and a string S
, make all appearances of all keywords in S
bold. Any letters between <b>
and </b>
tags become bold.
The returned string should use the least number of tags possible, and of course the tags should form a valid combination.
For example, given that
words = ["ab", "bc"]
and S = "aabcd"
, we should return "a<b>abc</b>d"
. Note that returning "a<b>a<b>b</b>c</b>d"
would use more tags, so it is incorrect.
Note:
words
has length in range[0, 50]
.words[i]
has length in range[1, 10]
.S
has length in range[0, 500]
.- All characters in
words[i]
andS
are lowercase letters.
class Solution { public String boldWords(String[] words, String S) { if (words == null || words.length == 0) { return S; } // step 1: find start and end pos of the substring // List<Interval> intervals = new ArrayList<>(); for (String t : words) { strStr(S, t, intervals); } if (intervals.isEmpty()) { return S; } // step 2: sort the intervals based on the start index // Collections.sort(intervals, new IntervalComparator()); // step 3: merge intervals // List<Interval> mergedIntervals = mergeIntervals(intervals); // step 4: compose the result based on the merged intervals // StringBuilder sb = new StringBuilder(); int prev = 0; for (int i = 0; i < mergedIntervals.size(); i++) { Interval curr = mergedIntervals.get(i); // prev seg // sb.append(S.substring(prev, curr.start)); sb.append("<b>"); // curr seg // sb.append(S.substring(curr.start, curr.end + 1)); sb.append("</b>"); prev = curr.end + 1; } // trailing substring // if (prev < S.length()) { sb.append(S.substring(prev)); } return sb.toString(); } private void strStr(String s, String t, List<Interval> list) { for (int i = 0; i < s.length() - t.length() + 1; i++) { int j = 0; while (j < t.length()) { if (s.charAt(i + j) == t.charAt(j)) { j++; } else { break; } } if (j == t.length()) { Interval interval = new Interval(i, i + j - 1); list.add(interval); } } } private List<Interval> mergeIntervals(List<Interval> intervals) { List<Interval> ans = new ArrayList<>(); if (intervals == null || intervals.isEmpty()) { return ans; } Interval prev = intervals.get(0); for (int i = 1; i < intervals.size(); i++) { Interval curr = intervals.get(i); if (prev.end >= curr.start || prev.end + 1 == curr.start) { prev.end = Math.max(prev.end, curr.end); } else { ans.add(new Interval(prev.start, prev.end)); prev = curr; } } ans.add(prev); return ans; } } class Interval { int start; int end; public Interval(int s, int e) { start = s; end = e; } } class IntervalComparator implements Comparator<Interval> { public int compare(Interval a, Interval b) { return a.start - b.start; } }
This comment has been removed by the author.
ReplyDelete