美文网首页
Java 算法 - 单词拆分I(动态规划)

Java 算法 - 单词拆分I(动态规划)

作者: 琼珶和予 | 来源:发表于2018-02-27 23:07 被阅读0次

  刚刚楼主做了一道关于动态规划的题,这道题其实不是很难,就是比较坑。

题意:

给出一个字符串s和一个词典,判断字符串s是否可以被空格切分成一个或多个出现在字典中的单词。

样例:

给出

s = "lintcode"

dict = ["lint","code"]

返回 true 因为"lintcode"可以被空格切分成"lint code"

1.n^2的解法(超时)

(1).解题思路

  这道题有两种方式来解决问题,一种方式的时间复杂度是n^2,一种是方式的时间复杂度是nk。
  我们先来看看n^2的解法。
  这道题其实一道典型的动态规划,而n^2的解法就是使用动态规划。
  第一步,首先,我们先定义一个一维数组dp,长度为string.length + 1,默认dp[0] = true,dp[i]表示的意思就是,string字符串0~i的子串是否能够符合要求;
  第二步,然后进行一次二重循环,第一重表示截取子串的起点,第二重表示截取子串的终点,如果当前截取的子串字典中出现过,那么dp[j] = dp[i] && dict.contains(s.substring(i, j))。

(2).代码

    public boolean wordBreak(String s, Set<String> dict) {
        boolean[] dp = new boolean[s.length() + 1];
        int minLength = getMinLength(dict);
        dp[0] = true;
        for (int i = 0; i < s.length(); i++) {
            if (!dp[i]) {
                continue;
            }
            for (int j = i + 1; j <= s.length(); j++) {
                //如果剩下的字符串的长度小于字典中最短字符串的长度
                //直接跳出
                if (s.length() - i < minLength) {
                    break;
                }
                //如果dp[j]为true,那么不能被重置
                //这是为了避免如果当前的dp[j]为true,但是在后面被重置为false
                //例如codecode1,如果在这里的dp[4] = true(dict为["code", "code1"])
                //但是后面dp[4]会被重置为false
                if (!dp[j]) {
                    dp[j] = dp[i] && dict.contains(s.substring(i, j));
                }

            }
        }
        return dp[s.length()];
    }


    private int getMinLength(Set<String> dict) {
        int min = Integer.MAX_VALUE;
        for (String string : dict) {
            min = Math.min(min, string.length());
        }
        return min;
    }

2.nk的解法

(1).解题思路

  nk的解法相较于n^2的解法,它的第二重循环遍历的是字典,而不是字符串。这里就不详细的解释,可以看代码理解理解。

    public boolean wordBreak(String s, Set<String> dict) {

        boolean[] dp = new boolean[s.length() + 1];
        dp[0] = true;
        for (int i = 0; i < s.length(); i++) {
            if(!dp[i]){
                continue;
            }
            for (String str : dict) {
                if (i + str.length() <= s.length() && s.substring(i, i + str.length()).equals(str))
                    dp[i + str.length()] = true;
            }
        }
        return dp[s.length()];
    }

相关文章

  • Java 算法 - 单词拆分I(动态规划)

      刚刚楼主做了一道关于动态规划的题,这道题其实不是很难,就是比较坑。 题意: 样例: 1.n^2的解法(超时) ...

  • python实现leetcode之140. 单词拆分 II

    解题思路 动态规划dp[i]表示到i为止有哪些切分方式 140. 单词拆分 II[https://leetcode...

  • 动态规划

    概念 动态规划(Dynamic Programming),是一种分阶段求解的方法。动态规划算法是通过拆分问题,定义...

  • JS动态规划算法--01背包问题

    动态规划 动态规划算法是通过拆分问题,定义问题状态和状态之间的关系,使得问题能够以递推(或者说分治)的方式去解决。...

  • 4. 动态规划算法

    1. 动态规划算法总结2. 漫画:什么是动态规划?3.算法之动态规划4. 动态规划-算法

  • Swift 算法实战:动态规划

    Swift 算法实战:动态规划 Swift 算法实战:动态规划

  • 剑指 Offer 14- I. 剪绳子

    这里用到的是动态规划 原长度是i,然后去看i-j和j是否需要拆分,分别来比较拆分和不拆分对结果的影响,讨论这四种情...

  • 算法练习:整数拆分(动态规划)

    一.前言 最近一直在了解动态规划,这是LeetCode上面的一道动规的题。 343. 整数拆分[https://l...

  • 2019-11-04 回溯算法

    package others; import java.util.Arrays; /** 动态规划算法计算10个工...

  • 算法- 单词拆分

    题目: 分析 题意:将s进行分割,分割后的多个字符串是否都可以在wordDict中找到。 第一种想法:将s进行分割...

网友评论

      本文标题:Java 算法 - 单词拆分I(动态规划)

      本文链接:https://www.haomeiwen.com/subject/tjjvxftx.html