给定一个非空字符串 s 和一个包含非空单词列表的字典 wordDict,判定 s 是否可以被空格拆分为一个或多个在字典中出现的单词。
说明:
- 拆分时可以重复使用字典中的单词。
- 你可以假设字典中没有重复的单词。
示例 1:
输入: s = "leetcode", wordDict = ["leet", "code"] 输出: true 解释: 返回 true 因为 "leetcode" 可以被拆分成 "leet code"。
示例 2:
输入: s = "applepenapple", wordDict = ["apple", "pen"] 输出: true 解释: 返回 true 因为 "applepenapple" 可以被拆分成 "apple pen apple"。注意你可以重复使用字典中的单词。
示例 3:
输入: s = "catsandog", wordDict = ["cats", "dog", "sand", "and", "cat"] 输出: false
思想:动态规划
f[i]表示s[0:i]是否可以拆分成词
转移方程:f[i] = f[j] && f[j:i] 0<=j<i (i处是否可以拆分成词=i之前的j处是否可以拆分成词 && 从j到i是否可以拆分成词)
c a t s a n d o g
↑ ↑
j i
bool dictContain(char *s,char **dict,int a,int b,int wordDictSize)
{
char *str=(char*)malloc(sizeof(char)*(b-a+1));
strncpy(str,s+a,b-a);
str[b-a]='\0';
for(int i=0;i<wordDictSize;i++)
{
if(strcmp(dict[i],str)==0)
{
//printf("%s ",str);
return true;
}
}
return false;
}
int wordBreak(char *s, char **dict,int wordDictSize)
{
int s_len=strlen(s);
int *arr=(int*)malloc(sizeof(int)*(s_len+1));
memset(arr,0,sizeof(arr)*(s_len+1));
arr[0]=1;
for(int i=1;i<=s_len;i++)
{
for(int j=0;j<i;j++)
{
if(arr[j] && dictContain(s,dict,j,i,wordDictSize))
{
arr[i]=1;
break;
}
}
}
return arr[s_len];
}
int main()
{
char *s="applepenapple";
char *dict[]={"apple","pen"};
printf("%d\n",wordBreak(s,dict,2));
return 0;
}