diff --git a/10. Regular Expression Matching/10. Regular Expression Matching.csproj b/10. Regular Expression Matching/10. Regular Expression Matching.csproj
new file mode 100644
index 0000000..061f772
--- /dev/null
+++ b/10. Regular Expression Matching/10. Regular Expression Matching.csproj
@@ -0,0 +1,11 @@
+
+
+
+ Exe
+ net10.0
+ _10._Regular_Expression_Matching
+ enable
+ enable
+
+
+
diff --git a/10. Regular Expression Matching/Program.cs b/10. Regular Expression Matching/Program.cs
new file mode 100644
index 0000000..fafea8a
--- /dev/null
+++ b/10. Regular Expression Matching/Program.cs
@@ -0,0 +1,29 @@
+var solution = new Solution();
+
+var examples = new (string s, string p, bool expected)[]
+{
+ ("aa", "a", false),
+ ("aa", "a*", true),
+ ("ab", ".*", true),
+ ("aab", "c*a*b", true),
+ ("mississippi", "mis*is*p*.", false),
+ ("mississippi", "mis*is*ip*.", true),
+ ("aaa", "a*a", true),
+ ("aaa", "ab*a*c*a", true),
+ ("ab", ".*c", false),
+ ("", "c*", true),
+ ("abcd", "d*", false),
+ ("", "", true),
+ ("a", ".", true),
+ ("", "a*", true),
+ ("aa", "b*a*", true),
+ ("a", "ab*", true),
+ ("abcaaaaaaabaabcabac", ".*ab.a.*a*a*.*b*b*", true),
+ ("", "a*b*", true),
+};
+
+foreach (var example in examples)
+{
+ var result = solution.IsMatch(example.s, example.p);
+ Console.WriteLine($"s = \"{example.s}\", p = \"{example.p}\" => {result} (expected {example.expected})");
+}
diff --git a/10. Regular Expression Matching/Solution.cs b/10. Regular Expression Matching/Solution.cs
new file mode 100644
index 0000000..d8bda39
--- /dev/null
+++ b/10. Regular Expression Matching/Solution.cs
@@ -0,0 +1,59 @@
+public class Solution
+{
+ public bool IsMatch(string s, string p) => IsMatch(null, s, p);
+
+ private bool IsMatch(char? prev, ReadOnlySpan str, ReadOnlySpan pattern)
+ {
+ if (pattern.Length == 0 && str.Length == 0)
+ return true;
+ if (str.Length == 0)
+ {
+ if (CanBeEmpty(pattern))
+ return true;
+ return false;
+ }
+ if (pattern.Length == 0)
+ return false;
+ var sym = str[0];
+ var p = pattern[0];
+ // раскрытая звёздочка
+ var pSymOrDot = p == '*' ? prev : p; // превращаем звёздочку в символ или точку
+ // ожидаемый текущий символ, конкретный
+ var pSym = pSymOrDot == '.' ? sym : pSymOrDot;
+
+
+ // следующий символ *
+ if (pattern.Length > 1 && pattern[1] == '*')
+ {
+ var match = false;
+ var i = 0;
+ do
+ {
+ match |= IsMatch(i > 0 ? p : prev, str[i..], pattern[2..]);
+ if (match || i == str.Length || str[i] != p && p != '.')
+ break;
+ i++;
+ }
+ while (i <= str.Length);
+ return match;
+ }
+ else if (sym != pSym)
+ {
+ return false;
+ }
+ else
+ {
+ return IsMatch(pSymOrDot, str[1..], pattern[1..]);
+ }
+ }
+
+ private bool CanBeEmpty(ReadOnlySpan pattern)
+ {
+ if (pattern.Length % 2 == 1)
+ return false;
+ for (var i = 1; i < pattern.Length; i += 2)
+ if (pattern[i] != '*')
+ return false;
+ return true;
+ }
+}
\ No newline at end of file
diff --git a/Leetcode.sln b/Leetcode.sln
index 4b3f035..c25662f 100644
--- a/Leetcode.sln
+++ b/Leetcode.sln
@@ -177,6 +177,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "347. Top K Frequent Element
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "5. Longest Palindromic Substring", "5. Longest Palindromic Substring\5. Longest Palindromic Substring.csproj", "{8F972144-7AF8-4860-9A9F-AB56D40D7C67}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "10. Regular Expression Matching", "10. Regular Expression Matching\10. Regular Expression Matching.csproj", "{0A6CECBE-AD75-4829-AAB2-D6D29EEECEB5}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -1231,6 +1233,18 @@ Global
{8F972144-7AF8-4860-9A9F-AB56D40D7C67}.Release|x64.Build.0 = Release|Any CPU
{8F972144-7AF8-4860-9A9F-AB56D40D7C67}.Release|x86.ActiveCfg = Release|Any CPU
{8F972144-7AF8-4860-9A9F-AB56D40D7C67}.Release|x86.Build.0 = Release|Any CPU
+ {0A6CECBE-AD75-4829-AAB2-D6D29EEECEB5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {0A6CECBE-AD75-4829-AAB2-D6D29EEECEB5}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {0A6CECBE-AD75-4829-AAB2-D6D29EEECEB5}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {0A6CECBE-AD75-4829-AAB2-D6D29EEECEB5}.Debug|x64.Build.0 = Debug|Any CPU
+ {0A6CECBE-AD75-4829-AAB2-D6D29EEECEB5}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {0A6CECBE-AD75-4829-AAB2-D6D29EEECEB5}.Debug|x86.Build.0 = Debug|Any CPU
+ {0A6CECBE-AD75-4829-AAB2-D6D29EEECEB5}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {0A6CECBE-AD75-4829-AAB2-D6D29EEECEB5}.Release|Any CPU.Build.0 = Release|Any CPU
+ {0A6CECBE-AD75-4829-AAB2-D6D29EEECEB5}.Release|x64.ActiveCfg = Release|Any CPU
+ {0A6CECBE-AD75-4829-AAB2-D6D29EEECEB5}.Release|x64.Build.0 = Release|Any CPU
+ {0A6CECBE-AD75-4829-AAB2-D6D29EEECEB5}.Release|x86.ActiveCfg = Release|Any CPU
+ {0A6CECBE-AD75-4829-AAB2-D6D29EEECEB5}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE