-
Notifications
You must be signed in to change notification settings - Fork 47
/
Copy path10.regular-expression-matching.java
137 lines (131 loc) · 3.53 KB
/
10.regular-expression-matching.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
/*
* @lc app=leetcode id=10 lang=java
*
* [10] Regular Expression Matching
*
* https://leetcode.com/problems/regular-expression-matching/description/
*
* algorithms
* Hard (25.20%)
* Likes: 2822
* Dislikes: 543
* Total Accepted: 321.3K
* Total Submissions: 1.3M
* Testcase Example: '"aa"\n"a"'
*
* Given an input string (s) and a pattern (p), implement regular expression
* matching with support for '.' and '*'.
*
*
* '.' Matches any single character.
* '*' Matches zero or more of the preceding element.
*
*
* The matching should cover the entire input string (not partial).
*
* Note:
*
*
* s could be empty and contains only lowercase letters a-z.
* p could be empty and contains only lowercase letters a-z, and characters
* like . or *.
*
*
* Example 1:
*
*
* Input:
* s = "aa"
* p = "a"
* Output: false
* Explanation: "a" does not match the entire string "aa".
*
*
* Example 2:
*
*
* Input:
* s = "aa"
* p = "a*"
* Output: true
* Explanation: '*' means zero or more of the preceding element, 'a'.
* Therefore, by repeating 'a' once, it becomes "aa".
*
*
* Example 3:
*
*
* Input:
* s = "ab"
* p = ".*"
* Output: true
* Explanation: ".*" means "zero or more (*) of any character (.)".
*
*
* Example 4:
*
*
* Input:
* s = "aab"
* p = "c*a*b"
* Output: true
* Explanation: c can be repeated 0 times, a can be repeated 1 time. Therefore,
* it matches "aab".
*
*
* Example 5:
*
*
* Input:
* s = "mississippi"
* p = "mis*is*p*."
* Output: false
*
*
*/
class Solution {
public boolean isMatch(String s, String p) {
if (s == null || p == null) {
return false;
}
return matchInternal(s, 0, p, 0);
}
public boolean matchInternal(String str, int strIndex, String pattern, int patternIndex) {
int strLength = str.length();
int patternLength = pattern.length();
// 如果匹配串和模式串都匹配结束
if (patternIndex == patternLength) {
return (strIndex == strLength);
}
// 如果匹配串匹配结束,模式串没有匹配结束,判断模式串第二个字符是不是 *
if (strIndex == strLength) {
if (patternIndex+1 < patternLength && pattern.charAt(patternIndex + 1) == '*') {
return matchInternal(str, strIndex, pattern, patternIndex + 2); // * 匹配 0 次
} else {
return false;
}
}
// 匹配串和模式串都没有匹配结束,区分模式串的第二个字符是不是*
if (patternIndex == patternLength-1 || pattern.charAt(patternIndex + 1) != '*') {
// 模式串只剩下一个字符,或者模式串的第二个字符不是*
if (matchOne(str, strIndex, pattern, patternIndex)) {
// 当前字符匹配成功,继续匹配下一个字符
return matchInternal(str, strIndex + 1, pattern, patternIndex + 1);
} else {
return false;
}
} else {
// 模式串的第二个字符是*
if (matchOne(str, strIndex, pattern, patternIndex)) {
return matchInternal(str, strIndex, pattern, patternIndex + 2) // * 匹配 0 次
|| matchInternal(str, strIndex + 1, pattern, patternIndex + 2) // * 匹配 1 次
|| matchInternal(str, strIndex + 1, pattern, patternIndex); // * 匹配 N 次
} else {
return matchInternal(str, strIndex, pattern, patternIndex + 2); // * 匹配 0 次
}
}
}
public boolean matchOne(String str, int strIndex, String pattern, int patternIndex) {
return pattern.charAt(patternIndex) == '.' || pattern.charAt(patternIndex) == str.charAt(strIndex);
}
}