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:

  1. Any left parenthesis '(' must have a corresponding right parenthesis ')'.
  2. Any right parenthesis ')' must have a corresponding left parenthesis '('.
  3. Left parenthesis '(' must go before the corresponding right parenthesis ')'.
  4. '*' could be treated as a single right parenthesis ')' or a single left parenthesis '(' or an empty string.
  5. An empty string is also valid.

Example 1:

Input: "()"
Output: True

Example 2:

Input: "(*)"
Output: True

Example 3:

Input: "(*))"
Output: True

Note:

  1. The string size will be in the range [1, 100].

判断给定的字符串的括号匹配是否合法, 20. Valid Parentheses 的变形,这题里只有小括号'()'和*,*号可以代表'(', ')'或者相当于没有。

解法1: 迭代

解法2: 递归,最容易想到的解法,用一个变量cnt记录左括号的数量,当遇到*号时分为三种情况递归下去。Python TLE,  C++: 1148 ms

解法2: 最优解法,设两个变量cmin和cmax,cmin最少左括号的情况,cmax表示最多左括号的情况,其它情况在[cmin, cmax]之间。遍历字符串,遇到左括号时,cmin和cmax都自增1;当遇到右括号时,当cmin大于0时,cmin才自减1,否则保持为0(因为其它*情况可能会平衡掉),而cmax减1;当遇到星号时,当cmin大于0时,cmin才自减1(当作右括号),而cmax自增1(当作左括号)。如果cmax小于0,说明到此字符时前面的右括号太多,有*也无法平衡掉,返回false。当循环结束后,返回cmin是否为0。

Java:

public boolean checkValidString(String s) {
int low = 0;
int high = 0;
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i) == '(') {
low++;
high++;
} else if (s.charAt(i) == ')') {
if (low > 0) {
low--;
}
high--;
} else {
if (low > 0) {
low--;
}
high++;
}
if (high < 0) {
return false;
}
}
return low == 0;
}

Python:

class Solution(object):
def checkValidString(self, s):
"""
:type s: str
:rtype: bool
"""
lower, upper = 0, 0 # keep lower bound and upper bound of '(' counts
for c in s:
lower += 1 if c == '(' else -1
upper -= 1 if c == ')' else -1
if upper < 0: break
lower = max(lower, 0)
return lower == 0 # range of '(' count is valid  

Python:

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

Python:

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 

Python: TLE

class Solution(object):
def checkValidString(self, s):
"""
:type s: str
:rtype: bool
"""
return self.helper(s, 0) def helper(self, s, count):
# if not s:
# return count == 0
if count < 0:
return False for i in xrange(len(s)):
if s[i] == '(':
count += 1
elif s[i] == ')':
if count <= 0:
return False
else:
count -= 1
else:
return self.helper(s[i+1:], count+1) or \
self.helper(s[i+1:], count) or \
self.helper(s[i+1:], count-1) return count == 0 if __name__ == '__main__':
print Solution().checkValidString("(((((*(()((((*((**(((()()*)()()()*((((**)())*)*)))))))(())(()))())((*()()(((()((()*(())*(()**)()(())")  

C++:

class Solution {
public:
bool checkValidString(string s) {
stack<int> left, star;
for (int i = 0; i < s.size(); ++i) {
if (s[i] == '*') star.push(i);
else if (s[i] == '(') left.push(i);
else {
if (left.empty() && star.empty()) return false;
if (!left.empty()) left.pop();
else star.pop();
}
}
while (!left.empty() && !star.empty()) {
if (left.top() > star.top()) return false;
left.pop(); star.pop();
}
return left.empty();
}
};

C++:

class Solution {
public:
bool checkValidString(string s) {
return helper(s, 0, 0);
}
bool helper(string s, int start, int cnt) {
if (cnt < 0) return false;
for (int i = start; i < s.size(); ++i) {
if (s[i] == '(') {
++cnt;
} else if (s[i] == ')') {
if (cnt <= 0) return false;
--cnt;
} else {
return helper(s, i + 1, cnt) || helper(s, i + 1, cnt + 1) || helper(s, i + 1, cnt - 1);
}
}
return cnt == 0;
}
};

C++:

class Solution {
public:
bool checkValidString(string s) {
int low = 0, high = 0;
for (char c : s) {
if (c == '(') {
++low; ++high;
} else if (c == ')') {
if (low > 0) --low;
--high;
} else {
if (low > 0) --low;
++high;
}
if (high < 0) return false;
}
return low == 0;
}
};

  

  

类似题目:  

[LeetCode] 20. Valid Parentheses 合法括号

  

All LeetCode Questions List 题目汇总

[LeetCode] 678. Valid Parenthesis String 验证括号字符串的更多相关文章

  1. [LeetCode] Valid Parenthesis String 验证括号字符串

    Given a string containing only three types of characters: '(', ')' and '*', write a function to chec ...

  2. [leetcode]678. Valid Parenthesis String验证有效括号字符串

    Given a string containing only three types of characters: '(', ')' and '*', write a function to chec ...

  3. leetcode 678. Valid Parenthesis String

    678. Valid Parenthesis String Medium Given a string containing only three types of characters: '(', ...

  4. 【LeetCode】678. Valid Parenthesis String 解题报告(Python)

    [LeetCode]678. Valid Parenthesis String 解题报告(Python) 标签(空格分隔): LeetCode 作者: 负雪明烛 id: fuxuemingzhu 个人 ...

  5. 678. Valid Parenthesis String

    https://leetcode.com/problems/valid-parenthesis-string/description/ 这个题的难点在增加了*,*可能是(也可能是).是(的前提是:右边 ...

  6. 【leetcode】Valid Parenthesis String

    题目: Given a string containing only three types of characters: '(', ')' and '*', write a function to ...

  7. [LeetCode] 680. Valid Palindrome II 验证回文字符串 II

    Given a non-empty string s, you may delete at most one character. Judge whether you can make it a pa ...

  8. [Swift]LeetCode678. 有效的括号字符串 | Valid Parenthesis String

    Given a string containing only three types of characters: '(', ')' and '*', write a function to chec ...

  9. LeetCode Valid Parenthesis String

    原题链接在这里:https://leetcode.com/problems/valid-parenthesis-string/description/ 题目: Given a string conta ...

随机推荐

  1. Kotlin调用Java程序重点分析

    在上一次https://www.cnblogs.com/webor2006/p/11530801.html中学习了Kotlin调用Java的使用方式及一些注意点,这次继续其这个场景进一步学习. 数组( ...

  2. POI不同浏览器导出名称处理

    /** * * @Title: encodeFileName * @Description: 导出文件转换文件名称编码 * @param @param fileNames * @param @para ...

  3. java处理异常的机制关键字为throw和throws

    在异常处理的过程中,throws和throw的区别是? throws:是在方法上对一个方法进行声明,而不进行处理,而是向上传,谁调用谁处理. throw:是在具体的抛出一个异常类型. throws的栗 ...

  4. Sql操作时间

    --. 当前系统日期.时间 -- ::27.277 --.时间操作 dateadd 在向指定日期加上一段时间的基础上,返回新的 datetime 值 dateadd(datepart,number,d ...

  5. c#3.0 Lambda 表达式

    使用c# 2.0 中的匿名方法查找“内部包含abc子串的所有字符串”: list.FindAll( delegate(string s) { renturn s.indexof("abc&q ...

  6. axure快速上手

    Axure RP是一个专业的快速原型设计工具.Axure(发音:Ack-sure),代表美国Axure公司:RP则是Rapid Prototyping(快速原型)的缩写.Axure RP是美国Axur ...

  7. 如何有效使用Project(1)——编制进度计划、保存基准

    1.前言: 软件产品的研发.升级.定制等,一般都是以项目的形式进行,此时项目进度计划以及资源使用情况就变成了项目经理关注的重点.如何让项目计划有效可控,及时暴露问题?如何查看资源的负荷情况,看资源分配 ...

  8. Xms Xmx PermSize MaxPermSize的含义

    参数的含义 -vmargs -Xms128M -Xmx512M -XX:PermSize=64M -XX:MaxPermSize=128M -vmargs 说明后面是VM的参数,所以后面的其实都是JV ...

  9. 自定义express中间件

    const http = require('http') class LikeExpress { constructor() { this.middleList = [] this.routes = ...

  10. eclipse spring MVC maven项目 maven install target下无war包

    1.排查问题 一步步去看,首先查看本地maven是否安装    命令:ctrl+r   cmd   输入  mvn -v  查看maven版本 2.查看  window>preference  ...