您的位置:首页 > 其它

Leetcode: Word Break

2014-01-07 23:02 281 查看
Given a string s and a dictionary of words dict, determine if s can be segmented into a space-separated sequence of one or more dictionary words.

For example, given
s = 
"leetcode"
,
dict = 
["leet", "code"]
.

Return true because 
"leetcode"
 can be segmented as 
"leet
code"
.

最开始试着写了一个简单递归的,时间复杂度过不了。

class Solution {
public:
bool wordBreak(string s, unordered_set<string> &dict) {
string str1, str2;
for (int i = s.size() - 1; i >= 0; --i) {
str1 = s.substr(0, i+1);
str2 = s.substr(i+1);
if (str1.empty() || dict.find(str1) != dict.end()) {
if (str2.empty() || dict.find(str2) != dict.end()) {
return true;
}
else {
if (wordBreak(str2, dict)) {
return true;
}
}
}
}

return false;
}
};
怎么办呢?每次调用workBreak应该可以利用以前计算的结果,正是DP,通过。

class Solution {
public:
bool wordBreak(string s, unordered_set<string> &dict) {
int size = s.size();
int **dp = new int*[size];
for (int i = 0; i < size; ++i) {
dp[i] = new int[size];
memset(dp[i], 0, sizeof(int)*size);
}

return wordBreakUtil(dict, dp, s, 0, size - 1);
}

bool wordBreakUtil(unordered_set<string> &dict, int **dp, string &s, int start, int end) {
if (start > end) {
return true;
}

string str1, str2;
for (int i = end; i >= start; --i) {
str1 = s.substr(start, i - start + 1);
str2 = s.substr(i+1);
if (dict.find(str1) != dict.end()) {
dp[start][i] = 1;
if (str2.empty()) {
return true;
}
else if (dict.find(str2) != dict.end()) {
dp[i+1][end] = 1;
return true;
}
else {
if (dp[i+1][end] == 0) {
if (wordBreakUtil(dict, dp, s, i + 1, end)) {
                           return true;
                       }
                       else {
                           dp[i+1][end] = -1;
                       }
                    }
}
}
else {
dp[start][i] = -1;
}
}

return false;
}
};
两维DP,空间用的比较多,在讨论区看到一个简单些的,用一维DP - dp[i]表示i之后的字符串是否可解。

class Solution {
public:
bool wordBreak(string s, unordered_set<string> &dict) {
int len = s.length();
vector<bool> dp(len + 1,false);
dp[len] = true;

for (int i = len - 1; i >= 0; --i) {
for (int j = i; j < len; ++j) {
string str = s.substr(i, j - i + 1);
if (dict.find(str) != dict.end() && dp[j + 1]) {
dp[i] = true;
break;
}
}
}

return dp[0];
}
};

================= 第二次==============

DP,有点类似求回文的思想,一开始用了两维的数组来保存状态。

class Solution {
public:
bool wordBreak(string s, unordered_set<string> &dict) {
int size = s.size();
vector<vector<bool>> breaks(size, vector<bool>(size, false));
for (int i = size - 1; i >= 0; --i) {
for (int j = i; j < size; ++j) {
if (dict.find(s.substr(i, j-i+1)) != dict.end()) {
breaks[i][j] = true;
if (j + 1 >= size || breaks[j+1][size-1]) {
breaks[i][size-1] = true;
break;
}
}
}
}

return breaks[0][size-1];
}
};


其实呢,一维就够了,只保存某个字符之后的字符串是否可解。

class Solution {
public:
bool wordBreak(string s, unordered_set<string> &dict) {
int size = s.size();
vector<bool> breaks(size, false);
for (int i = size - 1; i >= 0; --i) {
for (int j = i; j < size; ++j) {
if (dict.find(s.substr(i, j-i+1)) != dict.end()) {
if (j + 1 >= size || breaks[j+1]) {
breaks[i] = true;
break;
}
}
}
}

return breaks[0];
}
};

一年之后,还是想半天。。。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  leetcode dp