• 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:

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

    Note:

    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)。这样在字符串输入可以无限长的情况下就降一个维度了,很可以。

    具体处理:

    法1.用一个boolean[] isBold数组一开始这样标记好某个位置要不要加粗,后续进行加粗处理。

    法2.用Interval。一开始加入加粗区间,然后做一个mergeInterval,然后根据最后的intervals拼字符串。拼法最好是先用原来的,然后之后stringBuilder.insert(index, string); 而且注意每次加了以后后续再加标记都要再多一点offset。

    实现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:

    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;
        }
    }
  • 相关阅读:
    MSVCRTD.lib(crtexe.obj) : error LNK2019: 无法解析的外部符号 _main,该符号在函数 ___tmainCRTStart
    (转)Spring MVC
    ios>android>javaee
    css标准导航代码
    图片对齐问题
    display:inline、block、inline-block的区别
    css怎么引用某张图片?链接要怎么写
    论怎么写好一篇实验报告
    路由器及其配置方法
    (转)MyEclipse2014配置Tomcat开发JavaWeb程序JSP以及Servlet
  • 原文地址:https://www.cnblogs.com/jasminemzy/p/7975221.html
Copyright © 2020-2023  润新知