leetcode616- Add Bold Tag in String- medium

Given a string s and a list of strings dict, you need to add a closed pair of bold tag <b> and </b> 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:
"<b>abc</b>xyz<b>123</b>"

 

Example 2:app

Input: 
s = "aaabbcc"
dict = ["aaa","aab","bc"]
Output:
"<b>aaabbc</b>c"

 

Note:ui

  1. The given dict won't contain duplicates, and its length won't exceed 100.
  2. All the strings in input have length in range [1, 1000].

 

算法:關鍵是找需不須要加bold這個事情怎麼儘可能下降複雜度。這種問題通常輸入的字符串(L)可能很長很長的,但字典大小(k)通常是有限制的,因此儘可能避免對字符串i,j限制找是否是符合條件,由於這樣複雜度直接L^3了(雙重循環+contains查)。而是能夠換成for循環一次指着字符串開頭,而後for循環全部詞典來查看接下來的單詞是否是以詞典單詞爲前綴的 s.startsWith(word, i);,這樣時間複雜度是O(L^2 * K)。這樣在字符串輸入能夠無限長的狀況下就降一個維度了,很能夠。this

具體處理:spa

法1.用一個boolean[] isBold數組一開始這樣標記好某個位置要不要加粗,後續進行加粗處理。code

法2.用Interval。一開始加入加粗區間,而後作一個mergeInterval,而後根據最後的intervals拼字符串。拼法最好是先用原來的,而後以後stringBuilder.insert(index, string); 並且注意每次加了之後後續再加標記都要再多一點offset。blog

 

實現1:字符串

public class Solution {
    public String addBoldTag(String s, String[] dict) {
        boolean[] bold = new boolean[s.length()];
        for (int i = 0, end = 0; i < s.length(); i++) {
            for (String word : dict) {
                if (s.startsWith(word, i)) {
                    end = Math.max(end, i + word.length());
                }
            }
            bold[i] = end > i;
        }
        
        StringBuilder result = new StringBuilder();
        for (int i = 0; i < s.length(); i++) {
            if (!bold[i]) {
                result.append(s.charAt(i));
                continue;
            }
            int j = i;
            while (j < s.length() && bold[j]) j++;
            result.append("<b>" + s.substring(i, j) + "</b>");
            i = j - 1;
        }
        
        return result.toString();
    }
}

 

實現2:get

class Solution {
    private class Interval{
        public int start;
        public int end;
        public Interval(int start, int end) {
            this.start = start;
            this.end = end;
        }
    }

    public String addBoldTag(String s, String[] dict) {
        if (s == null || s.length() == 0 || dict == null || dict.length == 0) {
            return s;
        }
        Set<String> set = new HashSet<>();
        int maxL = Integer.MIN_VALUE;
        for (int i = 0; i < dict.length; i++) {
            set.add(dict[i]);
            maxL = Math.max(maxL, dict[i].length());
        }
        List<Interval> intervals = new ArrayList<>();
        for (int i = 0; i < s.length(); i++) {
            for (String word : dict) {
                if (s.startsWith(word, i)) {
                    intervals.add(new Interval(i, i + word.length() - 1));
                }
            }
            // 時間複雜度過高了
            // for (int j = i; j <= s.length() && j <= i + maxL + 1; j++) {
            //     if (set.contains(s.substring(i, j))) {
            //         intervals.add(new Interval(i, j - 1));
            //     }
            // }
        }

        if (intervals.size() == 0) {
            return s;
        }
        intervals = mergeIntervals(intervals);

        int offset = 0;
        StringBuilder sb = new StringBuilder(s);
        for (int i = 0; i < intervals.size(); i++) {
            // 注意insert這種操做
            sb.insert(intervals.get(i).start + offset, "<b>");
            offset += 3;
            sb.insert(intervals.get(i).end + 1 + offset, "</b>");
            offset += 4;
        }

        return sb.toString();
    }

    private List<Interval> mergeIntervals(List<Interval> intervals) {
        List<Interval> result = new ArrayList<>();
        Interval prev = intervals.get(0);
        Interval crt;
        for (int i = 1; i < intervals.size(); i++) {
            crt = intervals.get(i);
            if (crt.start <= prev.end + 1) {
                prev.end = Math.max(prev.end, crt.end);
            } else {
                result.add(prev);
                prev = crt;
            }
        }
        result.add(prev);
        return result;
    }
}
相關文章
相關標籤/搜索