问题
I was going through the question on LeetCode linked here.
Given a string containing only three types of characters: '(', ')' and '*', write a function to check whether this string is valid. We define the validity of a string by these rules:
- Any left parenthesis '(' must have a corresponding right parenthesis ')'.
- Any right parenthesis ')' must have a corresponding left parenthesis '('.
- Left parenthesis '(' must go before the corresponding right parenthesis ')'.
- '*' could be treated as a single right parenthesis ')' or a single left parenthesis '(' or an empty string.
- An empty string is also valid.
Example:
Input: "(*))"
Output: True
I've gone through the methods specified in the article but I'm unable to understand method 2 which is related to dynamic programming. Can anyone explain how do we need to approach the problem via dynamic programming? Thanks in advance!
Main pain point:
or, s[i] can be made to be '(', and there is some k in [i+1, j] such that s[k] can be made to be ')', plus the two intervals cut by s[k] (s[i+1: k] and s[k+1: j+1]) can be made valid;
回答1:
I'm not sure how much clearer we can make the explanation already offered in the LeetCode link you shared. The stated formulation for the dynamic program there is
Let dp[i][j] be true if and only if
the interval s[i], s[i+1], ..., s[j]
can be made valid.
First consider that any valid parenthetical construction can be reduced to a combination of self-contained valid sections, each one with their own left and right balanced ends. For example,
((()())())
has two inner sections at depth 1:
(valid_A valid_B)
where valid_A is (()())
and valid_B is ()
According to the problem description, a *
can be made into an empty string. This would cover the first case in the dynamic program formulation,
dp[i][j] is true if:
s[i] is '*', and the interval
s[i+1], s[i+2], ..., s[j]
can be made valid
since we would be looking at an already valid, or "self-contained," section of the input, from s[i+1]
to s[j]
, and adding nothing (an empty string) to it.
The second case for validity is if s[i]
can be (
, or the start of a valid section, in which case, if we can identify its specific balancing closing parenthesis, )
, at s[k]
, the two sections we can now identify would have to each be valid in order for the whole section to be valid. To take the former example,
((()())())
i k j
and use the language you have shared:
if s[i] can be made to be '(',
and there is some k in [i+1, j] such
that s[k] can be made to be ')'
which we have:
(()())()
i k j
"...plus the two intervals cut by s[k]
(s[i+1: k]
and s[k+1: j+1]
)..."; where s[i: j]
means the interval s[i], s[i+1], ..., s[j-1]
.
()() -> that's i+1...k-1
and
() -> that's k+1...j
"...can be made valid;" then the whole section s[i..j]
is valid.
来源:https://stackoverflow.com/questions/59520140/valid-parenthesis-string-leetcode