lintcode582 - Word Break II - hard


Given a string s and a dictionary of words dict, add spaces in s to construct a sentence where each word is a valid dictionary word.
Return all such possible sentences.
Example
Gieve s = lintcode,
dict = ["de", "ding", "co", "code", "lint"].
A solution is ["lint code", "lint co de"].

 

1.DFS,带记忆化搜索。
这题很容易TLE或MLE,尤其是当你试着扫描每段头尾不同的substring在不在字典里的时候会有很多重复功。减少时间复杂度的方法可以用记忆化搜索,比如1-5的分割我记下来了,以后6-10正好和1-5长一样,那我就不重新算,而是直接拿存过的分割结果了。实现这个功能的容器就是Map<String, List<String>>。
DFS函数头:private List<String> breakHelper(String s, Set<String> wordDict, Map<String, List<String>> memo)
目标:找出所有把s大卸八块的方式,拷贝一份放到memo里,再把这份方式返回。
流程:memo有了就直接拿了走人;遍历所有把s一分两半的方式,如果前半段字典里有,就DFS要一下所有后半段大卸八块的方式;把前半段和所有后半段的方式拼起来就是当前的结果了;存结果;返回结果。
细节:整个s就在字典里的情况要分出来处理,因为你没办法分s为s(0, length)和substring(length, length), 后面那样是编译错误的。

2.普通DFS
就是比较类似subset那些题目的做法,传index做,sb就像crt一样。但是会MLE哦,因为字典最长的可能也就5个字符,你一直拿30-1000的字符串去看在不在字典里,其实有很多无用功。前面那种做法其实也有这样做,但是它还是靠记忆化帮忙减少很多了,比如mmmmmmm…mmmmm走过一次流程发现没有分段方法,也会存个空集结果放到map里,下次再遇到一样的长字符串就不会再算了,直接返回空集上上级没办法粘出有效字符串。
细节:StringBuilder.delete(from, to)方法,里面填的参数和substring一样,头包括,尾包括,两者相减是长度。

 

 

1.DFS,带记忆化

public class Solution {
    /*
     * @param s: A string
     * @param wordDict: A set of words.
     * @return: All possible sentences.
     */
    public List<String> wordBreak(String s, Set<String> wordDict) {
        // write your code here
        List<String> result = new ArrayList<>();
        if (s == null || wordDict == null) {
            return result;
        }
        result = breakHelper(s, wordDict, new HashMap<String, List<String>>());
        return result;
    }
    
    private List<String> breakHelper(String s, Set<String> wordDict, Map<String, List<String>> memo) {
        
        if (memo.containsKey(s)) {
            return memo.get(s);
        }
        
        List<String> result = new ArrayList<>();
        for (int i = 1; i < s.length(); i++) {
            String substring = s.substring(0, i);
            if (!wordDict.contains(substring)) {
                continue;
            }
            List<String> suffixResult = breakHelper(s.substring(i), wordDict, memo);
            for (String item : suffixResult) {
                result.add(substring + " " + item);
            }
        }
        
        if (wordDict.contains(s)) {
            result.add(s);
        }
        
        memo.put(s, result);
        return result;
    }
}

 

2. 普通DFS,(正确但TLE)

public class Solution {
    /*
     * @param s: A string
     * @param wordDict: A set of words.
     * @return: All possible sentences.
     */
    public List<String> wordBreak(String s, Set<String> wordDict) {
        // write your code here
        List<String> result = new ArrayList<>();
        if (s == null || wordDict == null || (s.length() == 0 && !wordDict.contains(""))) {
            return result;
        }
        breakHelper(s, wordDict, 0, new StringBuilder(), result);
        return result;
    }
    
    private void breakHelper(String s, Set<String> wordDict, int index, StringBuilder sb, List<String> result) {
        
        if (index == s.length()) {
            result.add(sb.toString());
            return;
        }
        
        for (int i = index + 1; i <= s.length(); i++) {
            String substring = s.substring(index, i);
            if (!wordDict.contains(substring)) {
                continue;
            }
            if (index > 0) {
                sb.append(" ");
            }
            sb.append(substring);
            breakHelper(s, wordDict, i, sb, result);
            // 注意这个方法, 而且不可以sb.delete(index, i);,前面加了空格不一样了
            sb.delete(sb.length() - (i - index), sb.length());
            if (index > 0) {
                sb.delete(sb.length() - 1, sb.length());
            }
        }
    }
}

 

转载于:https://www.cnblogs.com/jasminemzy/p/9576750.html

变分模态分解(Variational Mode Decomposition, VMD)是一种强大的非线性、无参数信号处理技术,专门用于复杂非平稳信号的分析与分解。它由Eckart Dietz和Herbert Krim于2011年提出,主要针对传统傅立叶变换在处理非平稳信号时的不足。VMD的核心思想是将复杂信号分解为一系列模态函数(即固有模态函数,IMFs),每个IMF具有独特的频率成分和局部特性。这一过程与小波分析或经验模态分解(EMD)类似,但VMD通过变分优化框架显著提升了分解的稳定性和准确性。 在MATLAB环境中实现VMD,可以帮助我们更好地理解和应用这一技术。其核心算法主要包括以下步骤:首先进行初始化,设定模态数并为每个模态分配初始频率估计;接着采用交替最小二乘法,通过交替最小化残差平方和以及模态频率的离散时间傅立叶变换(DTFT)约束,更新每个模态函数和中心频率;最后通过迭代优化,在每次迭代中优化所有IMF的幅度和相位,直至满足停止条件(如达到预设迭代次数或残差平方和小于阈值)。 MATLAB中的VMD实现通常包括以下部分:数据预处理,如对原始信号进行归一化或去除直流偏置,以简化后续处理;定义VMD结构,设置模态数、迭代次数和约束参数等;VMD算法主体,包含初始化、交替最小二乘法和迭代优化过程;以及后处理,对分解结果进行评估和可视化,例如计算每个模态的频谱特性,绘制IMF的时频分布图。如果提供了一个包含VMD算法的压缩包文件,其中的“VMD”可能是MATLAB代码文件或完整的项目文件夹,可能包含主程序、函数库、示例数据和结果可视化脚本。通过运行这些代码,可以直观地看到VMD如何将复杂信号分解为独立模态,并理解每个模态的物理意义。 VMD在多个领域具有广泛的应用,包括信号处理(如声学、振动、生物医学信号分析)、图像处理(如图像去噪、特征提取)、金融时间序列分析(识
### 使用 `word-wrap` 和 `word-break` 实现换行效果 #### 属性解释 `word-wrap` 和 `word-break` 是 CSS 中用于控制文本换行行为的重要属性。 - **`word-wrap: break-word;`** 此属性主要用于处理超出容器宽度的内容,允许长单词或 URL 被拆分到下一行。它仅在必要时才会打断单词[^2]。 - **`word-break: break-all;`** 这一属性更加激进,会在任何字符处强行断开单词,即使不需要打破单词也会如此操作。这种特性非常适合包含大量英文或其他非亚洲语言的场景[^4]。 当应用于中文环境时,两者的区别主要体现在是否严格遵循语义分割上: - 对于纯中文内容来说,因为汉字之间不存在自然间隙(不像英文字母间存在空格),所以无论是采用 `word-wrap: break-word;` 或者是 `word-break: break-all;` 都能够正常工作并按需完成换行任务[^3]。 然而需要注意的是,在混合型文档——即既含有中文又夹杂着较长不可分割单元比如技术术语、链接地址等情况之下,则应仔细权衡选用哪一种策略更为合适[^1]。 以下是具体的应用实例以及代码展示部分: ```html <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>Word Wrap & Break Example</title> <style> .example { width: 200px; border: 1px solid black; margin-bottom: 10px; } /* Using word-wrap */ .use-word-wrap { white-space: pre-line; word-wrap: break-word; } /* Using word-break */ .use-word-break { white-space: normal; word-break: break-all; } </style> </head> <body> <div class="example use-word-wrap">这是一个非常长的单个词语aaaaaaaaaaaaaaaabbbbbbbbbbbbcccccccccccddddddddddeeeeeeeeee。</div> <div class="example use-word-break">这是另一个例子:http://www.example.com/verylongurlthatneedstobebrokenintopieces.</div> </body> </html> ``` 以上HTML片段展示了两种不同方法的实际运用情况。第一个 div 利用了 `word-wrap: break-word;` 来优雅地处理超长字符串;而第二个则通过设置 `word-break: break-all;` 达到了同样的目的却可能破坏某些特定场合下的可读性[^5]。 ### 结论 综上所述,在实际开发过程中可以根据项目需求灵活选择合适的解决方案。如果是针对一般性的网页布局设计,并且希望保持较好的用户体验,则推荐优先考虑使用 `word-wrap: break-word;` 。但如果面对特殊情形如表格内部单元格溢出等问题,则可以尝试引入更加强硬的方式 —— 即启用 `word-break: break-all;`.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值