liuxuhelloworld's notebook

题目链接

https://leetcode-cn.com/problems/word-break/

解答过程

这个题目是挺久以前写的了,第一时间也没有思路,看了下提交记录,发现还写过两种解法,但是一点印象也没有,很尴尬……

一开始写了个深度优先遍历的版本,理论上应该是对的,但是执行超时。代码如下:

    public boolean wordBreak(String s, List<String> wordDict) {
		return dfs(s, -1, 0, wordDict);
	}

	private boolean dfs(String s, int segmented, int cur, List<String> wordDict) {
		if (segmented == s.length() - 1) {
			return true;
		}

		if (cur == s.length()) {
			return false;
		}

		String str = s.substring(segmented + 1, cur + 1);
		if (wordDict.contains(str)) {
			if (dfs(s, cur, cur + 1, wordDict)) {
				return true;
			}
		}

		if (dfs(s, segmented, cur + 1, wordDict)) {
			return true;
		}

		return false;
	}

其实想一想,这个题目算是比较典型的动态规划题目了,想清楚状态转移方程即可。我们定义dp[i]表示s[0..i]对应的子串是否满足wordBreak,那么怎么得到dp[i+1]呢?

	public boolean wordBreak(String s, List<String> wordDict) {
		int length = s.length();

		boolean[] dp = new boolean[length + 1]; // dp[i] represents whether s[0..i-1] fits wordBreak
		dp[0] = true;

		for (int i = 1; i <= length; i++) {
			for (int j = i - 1; j >= 0; j--) {
				if (dp[j] && wordDict.contains(s.substring(j, i))) {
					dp[i] = true;
					break;
				}
			}
		}

		return dp[length];
	}