**[Lintcode]Word Break单词切分

本文介绍了一种字符串拆分算法,该算法使用递归方法检查给定字符串是否能被拆分为字典中的单词序列。通过逐步优化,从暴力解法到一维动态规划,实现了高效的解决方案。

Given a string s and a dictionary of words dict, determine if s can be break into a space-separated sequence of one or more dictionary words.

Example

Given s = "lintcode", dict = ["lint", "code"].

Return true because "lintcode" can be break as "lint code".

分析:Brute force。超时

public class Solution {
    /**
     * @param s: A string s
     * @param dict: A dictionary of words dict
     */
    public boolean wordBreak(String s, Set<String> dict) {
        if(s == null || s.length() == 0) return true;
        
        for(int i = 0; i < s.length(); i++) {
            if(dict.contains(s.substring(0, i + 1)) && wordBreak(s.substring(i + 1), dict))
                return true;
        }
        return false;
    }
}

二维动态规划:res[i][j]代表从i到j的子字符串是否可以匹配。仍然超时

public class Solution {
    /**
     * @param s: A string s
     * @param dict: A dictionary of words dict
     */
    public boolean wordBreak(String s, Set<String> dict) {
        if(s == null || s.length() == 0) return true;
        
        boolean[][] res = new boolean[s.length()][s.length()];
        if(dict.contains(s)) return true;
        
        for(int i = 0; i < s.length(); i++) {
            res[0][i] = dict.contains(s.substring(0, i + 1)) ? true : false;
        }
        for(int i = 0; i < s.length(); i++) {
            for(int j = i; j < s.length(); j++) {
                if(i == j && dict.contains(s.substring(i, i + 1))) {
                    res[i][j] = true;
                    continue;
                }
                for(int k = i; k <= j; k++) {
                    String tmp1 = s.substring(i, k + 1);
                    String tmp2 = s.substring(k + 1, j + 1);
                    if(k + 1 < s.length()) {
                        res[i][j] |= (res[i][k] || dict.contains(tmp1)) && (res[k + 1][j] ||
                            dict.contains(tmp2));  
                    } else {
                        res[i][j] |= (res[i][k] || dict.contains(tmp1));
                    }

                    if(res[i][j]) break;
                }
            }
        }
        return res[0][s.length() - 1];
    }
}

继续改进,使用一维动态规划。res[i]代表0到i的子字符串是否可以完成单词切分。一般动态规划是从i到i-1进行分析,但是这里要换一个角度,在i时,考虑i后边的i+k位置,k为每一个字符串可能的长度。


public class Solution {
    /**
     * @param s: A string s
     * @param dict: A dictionary of words dict
     */
    public boolean wordBreak(String s, Set<String> dict) {
        if(s == null || s.length() == 0) return true;
        
        boolean[] res = new boolean[s.length() + 1];
        res[0] = true;

        for(int i = 0; i < s.length(); i++) {
            if(!res[i])
                continue;
            else {
                for(String str : dict) {
                    int end = i + str.length();
                    if(end > s.length()) continue;
                    if(s.substring(i, end).equals(str))
                        res[end] = true;
                }
            }
        }
        return res[s.length()];
    }
}



你给出的 `.task-content` CSS 类用于控制网页中某个元素(如任务内容)的样式。下面是对每条 CSS 属性的详细解释和作用说明: --- ### ✅ 完整代码解释如下: ```css .task-content { word-wrap: break-word; /* 长单词自动换行 */ word-break: break-all; /* 当单词过长时强制截断 */ padding: 2px 0; /* 适当增加内边距 */ max-width: calc(100% - 90px); /* 限制内容最大宽度 */ } ``` --- ### 🔍 属性详解: 1. **`word-wrap: break-word;`** - 作用:允许长单词或 URL 地址在超出容器宽度时自动换行。 - 适用场景:防止内容溢出容器,特别是当内容包含长字符串(如长 URL、长单词)时非常有用。 - 注意:这个属性现在已被 `overflow-wrap` 取代,但 `word-wrap` 仍然广泛支持。 2. **`word-break: break-all;`** - 作用:强制在任意字符之间换行,即使这会打断一个单词。 - 与 `word-wrap: break-word` 的区别: - `break-all` 会更激进地打断单词。 - `break-word` 更倾向于保持单词完整,只在必要时打断。 - 适用场景:适用于内容不可控、可能出现极长字符串的场景。 3. **`padding: 2px 0;`** - 作用:为元素的上下设置内边距,值为 `2px`,左右为 `0`。 - 效果:使内容在垂直方向上不会紧贴边框,提升可读性。 4. **`max-width: calc(100% - 90px);`** - 作用:设置元素的最大宽度为其父容器宽度减去 `90px`。 - 举例:如果父容器宽度是 `1000px`,则 `.task-content` 最大宽度为 `910px`。 - 使用 `calc()` 函数:可以动态计算宽度,非常适用于响应式设计。 --- ### 📌 使用建议: - 如果你希望保留单词的完整性,可以移除 `word-break: break-all;`,仅保留 `word-wrap: break-word;`。 - 如果你希望 `.task-content` 在某些设备上表现不同,可以使用媒体查询进一步优化。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值