The number of open parenthesis is in a range `[cmin, cmax]`

`cmax`

counts the maximum open parenthesis, which means the maximum number of unbalanced '(' that **COULD** be paired.

`cmin`

counts the minimum open parenthesis, which means the number of unbalanced '(' that **MUST** be paired.

The string is valid for 2 condition:

`cmax`

will never be negative.`cmin`

is 0 at the end.

```
def checkValidString(self, s):
cmin = cmax = 0
for i in s:
if i == '(':
cmax += 1
cmin += 1
if i == ')':
cmax -= 1
cmin = max(cmin - 1, 0)
if i == '*':
cmax += 1
cmin = max(cmin - 1, 0)
if cmax < 0:
return False
return cmin == 0
```

or shorter:

```
def checkValidString(self, s):
cmin = cmax = 0
for i in s:
cmax = cmax-1 if i==")" else cmax+1
cmin = cmin+1 if i=='(' else max(cmin - 1, 0)
if cmax < 0: return False
return cmin == 0
```

Edited after vonzcy's suggestion.