一、题目还原
给定一个只包含 ‘(’ 和 ‘)’ 的字符串,找出最长的包含有效括号的子串的长度。
示例 1:
输入: “(()”
输出: 2
解释: 最长有效括号子串为 “()”
示例 2:
输入: “)()())”
输出: 4
解释: 最长有效括号子串为 “()()”
二、解题思路
① 定义左右括号数leftNum、rightNum,以及有效括号的起始点下标begin
② 从左至右遍历记录左右括号数,如果leftNum==rightNum,说明构成有效括号,记录此时遍历到的下标到begin组成的长度
③ 如果leftNum<rightNum,说明前面构成的子串不是一个有效的括号,将begin已至此处下一位重复上一步骤
④ 一直遍历可能存在leftNum>rightNum恒成立,导致无法记录有效括号,则需要从右至左再次遍历一次,重复以上步骤
三、代码展示
① main函数
public static void main(String[] args) {
String s = "()(()())";
System.out.println(longestValidParentheses(s));
}
② longestValidParentheses方法函数
public static int longestValidParentheses(String s) {
int begin = 0;
int index = 0;
int leftNum = 0;
int rightNum = 0;
int maxLength = 0;
String maxStr = "";
while(index < s.length()){
if("(".equals(s.substring(index,index+1))){
leftNum ++;
}else if(")".equals(s.substring(index,index+1))){
rightNum ++;
if(leftNum == rightNum){
maxStr = s.substring(begin,index+1);
}else if(leftNum < rightNum){
maxLength = maxLength > maxStr.length() ? maxLength : maxStr.length();
if(s.length() - index < maxLength) break;
rightNum = 0;
leftNum = 0;
begin = index + 1;
}
}
index ++;
}
maxLength = maxLength > maxStr.length() ? maxLength : maxStr.length();
if(maxLength > s.length() / 2){
return maxLength;
}
leftNum = 0;
rightNum = 0;
index = s.length();
begin = s.length();
while(index > 0){
if(")".equals(s.substring(index-1,index))){
rightNum ++;
}else if("(".equals(s.substring(index-1,index))){
leftNum ++;
if(leftNum == rightNum){
maxStr = s.substring(index-1,begin);
}else if(leftNum > rightNum){
maxLength = maxLength > maxStr.length() ? maxLength : maxStr.length();
if(index < maxLength) break;
rightNum = 0;
leftNum = 0;
begin = index - 1;
}
}
index --;
}
return maxLength > maxStr.length() ? maxLength : maxStr.length();
}
控制台输出:
8
Process finished with exit code 0
四、自我总结
LeetCode第32题,难度为困难。博主因为和朋友聊天过程中商讨到这道题,临时有了思路,于是跳了一部分题先做本道题。博主一开始没有考虑到左括号数一直大于右括号数情况,以为写出来的代码简单效率会高一些,万万没想到越写越乱,到最后又循环遍历了一遍才得到结果,效率上肯定是很低的。想着优化一下,在第一次遍历完,只要得到的最大长度已经超过该字符串一半的长度就可以直接返回值不用进行第二次遍历,但是从提交结果上看并没有很高的提升。
朋友说使用栈的模型来解决这道题会好些,博主后期会研究研究。
- 博主最近也将刷题的代码上传到github中,欢迎各位大佬们指点一二
Github仓库地址:https://github.com/w735937076/LeetCode