leetcode139 单词拆分

leetcode139 单词拆分

题目详情

leetcode139 单词拆分_第1张图片

题目解析

递归(有记忆递归)

根据题目可以试想,如果确定字符串前 i 个字符能是wordDict中的单词,那么只要半段第 i 个 字符以后的字符串是否能够拆分即可。因此可以采用递归的方式进行穷举。
为了能够更快的查找到wordDict是否包含字符串,可以将wordDict 转换成HashSet。
直接进行递归的时间复杂度为 O(n^n)
递归过程中会产生很多冗余的计算,为了能够减少冗余计算,可以维持一个memo数组进行记忆,减少重复计算开销
有记忆的递归时间复杂度为 O(n^2)


/**
 * 有记忆递归
 */

public class Solution4 {
    public boolean wordBreak(String s, List<String> wordDict){
        Set<String> wordSet = new HashSet<String>(wordDict);
        return helper(s, wordSet, 0, new Boolean[s.length()]);
    }

    private boolean helper(String s, Set<String> wordDict, int start, Boolean[] memo){
        if(start == s.length())
            return true;
        if(memo[start] != null)
            return memo[start];
        for(int i = start + 1; i <= s.length(); i ++){
            if(wordDict.contains(s.substring(start, i))){
                memo[start] = helper(s, wordDict, i, memo);
                if(memo[start])
                    return true;
            }
        }
        memo[start] = false;
        return false;

    }
}

动态规划

对于字符串 s 可以拆分成两个字符串 s1 和 s2 ,如果 s1 和 s2 都能被拆分,那么字符串 s 也能拆分。因此,我们可以采用动态规划的方式进行遍历求解,维护一个数组 boolean dp[s.length() + 1],其中的第 i 个元素表示在第 i 个字符后便分割成两个字符串。其中dp[0] = true, 依次求出 dp 数组中的每一个元素,最终返回结果为 dp[s.length()]
时间复杂度为 O(n^2)

/**
 * 动态规划
 */

public class Solution5 {
    public boolean wordBreak(String s, List<String> wordDict){
        Set<String> wordSet = new HashSet<String>(wordDict);
        boolean[] dp = new boolean[s.length() + 1];
        dp[0] = true;
        for(int i = 1; i < s.length() + 1; i ++){
            for(int j = 0; j < i; j ++){
                if(dp[j] && wordSet.contains(s.substring(j, i))){
                    dp[i] = true;
                    break;
                }
            }
        }
        return dp[s.length()];
    }
}

你可能感兴趣的:(leetcode,Java,字符串,数据结构,java,算法,leetcode)