这个C语言版本花了一点时间,主要因为两个方面:
1. 变量定义数组的长度,需要事先申请内存
2. 题目本身的逻辑,看了个Java改编的C版本,好像Java版本本来也有点问题。
/*
1, If p.charAt(j) == s.charAt(i) : dp[i][j] = dp[i-1][j-1];
2, If p.charAt(j) == '.' : dp[i][j] = dp[i-1][j-1];
3, If p.charAt(j) == '*':
here are two sub conditions:
1 if p.charAt(j-1) != s.charAt(i) : dp[i][j] = dp[i][j-2] //in this case, a* only counts as empty
2 if p.charAt(i-1) == s.charAt(i) or p.charAt(i-1) == '.':
dp[i][j] = dp[i-1][j] //in this case, a* counts as multiple a
or dp[i][j] = dp[i][j-1] // in this case, a* counts as single a
or dp[i][j] = dp[i][j-2] // in this case, a* counts as empty
*/
bool isMatch(char* s, char* p) {
if(!s||!p) return false;
int sLen = strlen(s);
int pLen = strlen(p);
int **dp;
dp = (int **)malloc(sizeof(int *) * (sLen+1));//分配指针数组
for(int i=0; i<sLen+1; i++)
{
dp[i] = (int *)malloc(sizeof(int) * (pLen+1));//分配每个指针所指向的数组
}
dp[0][0] = 1;
for (int i = 0; i< pLen; i++)
{
if(p[i]=='*'&& dp[0][i-1])
{
dp[0][i+1] = 1;//默认第一个字符不会是*,所以不会越界
}
}
for(int j=0; j<sLen ; j++)
{
for(int k=0; k<pLen; k++) {
if (p[k] == '.') {
dp[j + 1][k + 1] = dp[j][k];
}
else if (p[k] == s[j]) {
dp[j + 1][k + 1] = dp[j][k];
}
else if (p[k] == '*') {
//if (p[k - 1] != s[j] && p[k - 1] != '.') {
// dp[j + 1][k + 1] = dp[j + 1][k - 1];
//} else {
// dp[j + 1][k + 1] = (dp[j + 1][k] || dp[j][k + 1] || dp[j + 1][k - 1]);
// }
dp[j+1][k+1] = dp[j+1][k-1] || dp[j+1][k] || (dp[j][k+1] && (s[j]==p[k-1] || p[k-1]=='.'));
}
}
}
return dp[sLen][pLen]==1?true:false;
}
C++版本
class Solution {
public:
bool isMatch(string s, string p) {
int m = s.size(), n = p.size();
vector<vector<bool>> dp(m + 1, vector<bool>(n + 1, false));
dp[0][0] = true;
for (int i = 0; i <= m; ++i) {
for (int j = 1; j <= n; ++j) {
if (j > 1 && p[j - 1] == '*') {
dp[i][j] = dp[i][j - 2] || (i > 0 && (s[i - 1] == p[j - 2] || p[j - 2] == '.') && dp[i - 1][j]);
} else {
dp[i][j] = i > 0 && dp[i - 1][j - 1] && (s[i - 1] == p[j - 1] || p[j - 1] == '.');
}
}
}
return dp[m][n];
}
};
这里给出的都是动态规划法写的版本。
给大家看一个C语言4ms的范例,LeetCode有一点就是,你提交通过了才能看到别人更好的代码。
typedef struct{
char p;
char s;
}data;
bool isMatch(char* s, char* p) {
int lp = strlen(p), ls = strlen(s), e = 0, i, j;
data *cp = malloc(sizeof(data) * lp);
for (i = 0; i < lp; ++i){
if (p[i] == '*'){
cp[e-1].s = 1;
}else{
cp[e].p = p[i];
cp[e].s = 0;
e++;
}
}
int *dp = malloc(sizeof(int) * (ls + 1) * (e + 1));
memset(dp, 0, sizeof(int) * (ls + 1) * (e + 1));
dp[0] = 1;
for (i = 0; i < ls; ++i){
for (j = 0; j < e; ++j){
if (dp[i * (e+1) + j]){
if (cp[j].p == '.'){
if (cp[j].s == 0){
dp[(i+1) * (e+1) + (j+1)] = 1;
}else{
int k;
for (k = i; k <= ls; ++k){
dp[k * (e+1) + (j+1)] = 1;
}
}
}else{
if (cp[j].s == 0){
if (cp[j].p == s[i]){
dp[(i+1) * (e+1) + (j+1)] = 1;
}
}else{
int k;
dp[i * (e+1) + (j+1)] = 1;
for (k = i; cp[j].p == s[k] && k < ls; ++k){
dp[(k+1) * (e+1) + (j+1)] = 1;
}
}
}
}
}
}
for (j = 0; j < e; ++j){
if (dp[ls * (e+1) + j] && cp[j].s == 1){
dp[ls * (e+1) + (j+1)] = 1;
}
}
int res = dp[ls * (e+1) + e];
free(dp);
free(cp);
return res;
}
再来一个8ms的,主要看看这个二维数组的定义,竟然可以直接定义。。。。
bool isMatch(char* s, char* p) {
int m = strlen(s);
int n = strlen(p);
int i,j;
bool dp[m+1][n+1];
dp[0][0] = true;
for ( i = 1; i <= m; i++)
dp[i][0] = false;
for (j = 1; j <= n; j++)
dp[0][j] = j > 1 && '*' == p[j - 1] && dp[0][j - 2];
for(i = 1;i <= m;i++)
{
for(j = 1;j <= n;j++)
{
if(p[j-1] == '*')
dp[i][j] = dp[i][j-2] || (s[i-1] == p[j-2] || p[j-2] == '.') && dp[i-1][j];
else
dp[i][j] = (p[j-1] == '.' || s[i-1] == p[j-1]) && dp[i-1][j-1];
}
}
return dp[m][n];
}