@@ -0,0 +1,14 @@
|
|||||||
|
// This file is generated by mkfile.py
|
||||||
|
// Date: 2026-06-26
|
||||||
|
|
||||||
|
#ifndef INC_32_H
|
||||||
|
#define INC_32_H
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
int longestValidParentheses(char *s);
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif // INC_32_H
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
// This file is generated by mkfile.py
|
||||||
|
// Date: 2026-06-26
|
||||||
|
|
||||||
|
#include <solution/32.h>
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#define max(x, y) ((x) > (y) ? (x) : (y))
|
||||||
|
|
||||||
|
int longestValidParentheses(char *s)
|
||||||
|
{
|
||||||
|
int result = 0;
|
||||||
|
int m = strlen(s);
|
||||||
|
|
||||||
|
if (m < 2)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
int *dp = malloc(sizeof(int) * m);
|
||||||
|
memset(dp, 0, sizeof(int) * m);
|
||||||
|
|
||||||
|
// i: current index, we skipped 0 because one char can not
|
||||||
|
// be paired
|
||||||
|
// dp[i]: use i as the end of string, see how much parentheses
|
||||||
|
// can be matched before i
|
||||||
|
for (int i = 1; i < m; i++)
|
||||||
|
{
|
||||||
|
// if current char is "(" it can not be matched, a valid
|
||||||
|
// match must be ended with ")". we just check s[i] == ')'
|
||||||
|
if (s[i] == ')')
|
||||||
|
{
|
||||||
|
// so there are 2 match situations:
|
||||||
|
// 1. s[i - 1] == '('. it can match current ')'. we also
|
||||||
|
// need to check before it if we had a valid pair.
|
||||||
|
if (s[i - 1] == '(')
|
||||||
|
{
|
||||||
|
if (i > 1)
|
||||||
|
dp[i] = dp[i - 2] + 2;
|
||||||
|
else
|
||||||
|
dp[i] = 2;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// 2. s[i - 1] == ')'. it means there maybe has valid pair
|
||||||
|
// before. we need to know how much pairs before i. we
|
||||||
|
// can read it from dp[i], then we can get char before
|
||||||
|
// valid pair. like situation 1, if char == '(' it can
|
||||||
|
// be matched. but we need to noticed, if there is no
|
||||||
|
// valid pair before, this ')' must be ignored.
|
||||||
|
int k = i - dp[i - 1] - 1;
|
||||||
|
if (k < 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (s[k] == '(')
|
||||||
|
{
|
||||||
|
// if k > 1, see if we can add a valid pair before k
|
||||||
|
if (k > 1)
|
||||||
|
dp[i] = dp[i - 1] + dp[k - 1] + 2;
|
||||||
|
else
|
||||||
|
dp[i] = dp[i - 1] + 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < m; i++)
|
||||||
|
result = max(dp[i], result);
|
||||||
|
|
||||||
|
free(dp);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
// This file is generated by mkfile.py
|
||||||
|
// Date: 2026-06-26
|
||||||
|
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
#include <solution/32.h>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
class LongestValidParenthesesTest : public ::testing::Test
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
void AssertLongestValidParentheses(const std::string &input, int expected)
|
||||||
|
{
|
||||||
|
std::vector<char> buffer(input.begin(), input.end());
|
||||||
|
buffer.push_back('\0');
|
||||||
|
|
||||||
|
EXPECT_EQ(longestValidParentheses(buffer.data()), expected);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_F(LongestValidParenthesesTest, Example1)
|
||||||
|
{
|
||||||
|
AssertLongestValidParentheses("(()", 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(LongestValidParenthesesTest, Example2)
|
||||||
|
{
|
||||||
|
AssertLongestValidParentheses(")()())", 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(LongestValidParenthesesTest, Example3)
|
||||||
|
{
|
||||||
|
AssertLongestValidParentheses("", 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(LongestValidParenthesesTest, ReturnsZeroWhenThereIsNoValidPair)
|
||||||
|
{
|
||||||
|
AssertLongestValidParentheses("(", 0);
|
||||||
|
AssertLongestValidParentheses(")", 0);
|
||||||
|
AssertLongestValidParentheses("((((", 0);
|
||||||
|
AssertLongestValidParentheses("))))", 0);
|
||||||
|
AssertLongestValidParentheses(")(", 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(LongestValidParenthesesTest, EntireStringIsValid)
|
||||||
|
{
|
||||||
|
AssertLongestValidParentheses("()", 2);
|
||||||
|
AssertLongestValidParentheses("()()", 4);
|
||||||
|
AssertLongestValidParentheses("(())", 4);
|
||||||
|
AssertLongestValidParentheses("(()())", 6);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(LongestValidParenthesesTest, FindsValidSubstringAfterInvalidPrefix)
|
||||||
|
{
|
||||||
|
AssertLongestValidParentheses(")()", 2);
|
||||||
|
AssertLongestValidParentheses("())(())", 4);
|
||||||
|
AssertLongestValidParentheses("())()()", 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(LongestValidParenthesesTest, FindsLongestContiguousSubstring)
|
||||||
|
{
|
||||||
|
AssertLongestValidParentheses("()(()", 2);
|
||||||
|
AssertLongestValidParentheses("(()(((()", 2);
|
||||||
|
AssertLongestValidParentheses("(()())())", 8);
|
||||||
|
AssertLongestValidParentheses("()(())", 6);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(LongestValidParenthesesTest, HandlesMultipleSeparatedValidBlocks)
|
||||||
|
{
|
||||||
|
AssertLongestValidParentheses("()(()())", 8);
|
||||||
|
AssertLongestValidParentheses("())(()())", 6);
|
||||||
|
AssertLongestValidParentheses("(()())())(()(()))", 8);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user