LeetCode 32最长有效括号(困难)

简介: 给定一个只包含 ‘(’ 和 ‘)’ 的字符串,找出最长的包含有效括号的子串的长度。

题目描述



给定一个只包含 ‘(’ 和 ‘)’ 的字符串,找出最长的包含有效括号的子串的长度。

示例 1:


输入: “(()”

输出: 2

解释: 最长有效括号子串为 “()”


示例 2:

输入: “)()())”

输出: 4

解释: 最长有效括号子串为 “()()”


分析

再看这题之前,咱们回顾一下前面刷过的题。力扣20有效的括号


20200926121454545.png


分析



这种题核心思想就是使用栈模拟。本题的话更简单一点因为只有()两种括号,只有两个东西的话很多时候可以省略很多内容。在使用暴力的时候就可以循环每次找到最长的有效括号。而括号匹配的时候可以直接终止的情况是当前多个)右括号。例如())(到第三个不可能和前面相连,而如果来(只需要期待后面能够来)。一个)可以和一个(组成一对,消除栈中的一个(


当然,在具体的实现上,我们用数组模拟栈,实现代码为:


public  int longestValidParentheses(String s) {
  char str[]=s.toCharArray();//字符数组
  int max=0;
  for(int i=0;i<str.length-1;i++)
  {
    int index=-1;
    if(max>=str.length-i)
      break;
    for(int j=i;j<str.length;j++)
    {
      if(str[j]=='(')
        index++;
      else {
        if(index<0)
        {
          i=j;
          break;
        }
        else {
          index--;
        }
      }
      if(index==-1&&(j-i+1>max))
      {
        max=j-i+1;
      }
    }
  } 
  return max;
   }


尽管有一些地方有优化空间,比如剪枝把各种不可能的给剪掉,但整个算法还是太复杂,算法的复杂度为O(n2).并且只击败5%的人,所以在这方面宣告算法宣告失败:


2020092613455176.png

其实这个暴力是昨晚睡觉前过的, 因为我看到困难级别我在刷的时候用暴力过了好歹我也是过了,过了之后上床之后我就在想怎么去优化这道题。


在今天早上的时候用笔画了画想了想成功攻破该题(看不懂不要紧,下面给你慢慢讲):


20200926150413845.png


如何将这道题从一个O(n2)的时间复杂度优化到O(n)?很容易, 我们需要注意他的过程。我们先随便看几个可能的最大情况。


( ) ) ( ) ( ( ) ( ) ) 最大为后面部分

( ) ( ) ( ( ( ) 最大为前面部分

( ( ( ( ( ( ) ( ) ( ) ( ) 最大为后面部分


对于这么一次获取你会发现不同括号会有些区别:


(:左括号一旦出现那么他就期待一个)进行匹配,但它的后面可能有)并且在这中间有很多其他括号对。


):右扩号有两种情况:


  • 一种是当前已经超过左括号前面已经不可能连续了。例如( ) ) ( )第三个括号出现已经使得整个串串不可能连续,最大要么在其左面要么再其右面。 你可以理解其为一种清零初始机制。
  • 另一种情况)就是目标栈中存在(可与其进行匹配。匹配之后要叠加到消除后平级的数量上,并且判断是否是最大值。(下面会解释)


具体实现的思路上,就是使用一个int数组标记当前层级(栈深)有正确的括号数量。 模拟一次栈行为从左向右,遇到)太多(当前栈中不存在(进行匹配)就将数据清零重新开始。这样一直到最后。你可以把它看成台接,遇到(就上一个台阶并清零该新台阶,遇到)就下一个台阶并且把数量加到下降后的台阶上。具体可以看下面图片模拟呃过程:

( ) ( ( ) ( ) ( ( ) ) )


20200926204106127.png


仔细看看这张图,具体实现代码为:


 public static int longestValidParentheses(String s) {
    int max=0;  
    int value[]=new int[s.length()+1];
    int index=0;
    for(int i=0;i<s.length();i++)
    {
      if(s.charAt(i)=='(')
      {
        index++;
        value[index]=0;
      }
      else {//")"
        if(index==0)
        {
          value[0]=0;
        }
        else {
            value[index-1]+=value[index--]+2;//叠加
            if(value[index]>max)//更新
              max=value[index];
        }
      }
    }
    return max;
    }


20200926204540756.png

好啦,这个O(n)的复杂度还行,至于其他解法也没研究有空可以看看。这次打卡就结束啦,如果有兴趣的欢迎关注公众号bigsai 回复进群,加入打卡!一起刷题。

目录
相关文章
|
6月前
|
存储 C语言 索引
环形链表、环形链表 II、有效的括号​​​​​​​【LeetCode刷题日志】
环形链表、环形链表 II、有效的括号​​​​​​​【LeetCode刷题日志】
|
14天前
|
存储 算法 Java
leetcode算法题-有效的括号(简单)
【11月更文挑战第5天】本文介绍了 LeetCode 上“有效的括号”这道题的解法。题目要求判断一个只包含括号字符的字符串是否有效。有效字符串需满足左括号必须用相同类型的右括号闭合,并且左括号必须以正确的顺序闭合。解题思路是使用栈数据结构,遍历字符串时将左括号压入栈中,遇到右括号时检查栈顶元素是否匹配。最后根据栈是否为空来判断字符串中的括号是否有效。示例代码包括 Python 和 Java 版本。
|
1月前
|
算法 C++
Leetcode第二十二题(括号生成)
这篇文章讨论了如何使用递归算法解决LeetCode第22题“括号生成”的问题,提供了两种C++的实现方法,目的是生成所有有效的括号组合。
17 0
Leetcode第二十二题(括号生成)
|
1月前
|
存储 C++ 容器
Leetcode第二十题(有效的括号)
这篇文章介绍了如何使用栈来解决LeetCode第20题“有效的括号”问题,提供了两种方法:数组栈和容器栈,以及相应的C++代码实现。
17 0
|
3月前
|
算法
LeetCode第22题括号生成
该文章介绍了 LeetCode 第 22 题括号生成的解法,通过回溯算法生成所有可能的括号组合,在递归过程中根据左右括号数量的条件进行剪枝,从而得到有效的括号组合。
LeetCode第22题括号生成
|
3月前
|
存储 算法
LeetCode第20题有效的括号
该文章介绍了 LeetCode 第 20 题有效的括号的解法,通过分析有效括号的特征,使用栈结构存储括号关系,判断遇到右边括号时栈顶是否有匹配的左边括号,从而解决问题,同时总结了栈的先进后出结构可用于解决有规律的符号匹配问题。
LeetCode第20题有效的括号
|
3月前
|
算法 Python
【Leetcode刷题Python】括号匹配问题
一种解决括号匹配问题的Python实现方法,通过计算给定括号串的所有子串的最长合法括号子序列长度之和来确定权值。
25 0
|
3月前
|
机器学习/深度学习 Python
【Leetcode刷题Python】22. 括号生成
本文介绍了了LeetCode题目22的两种Python编程解决方案,题目要求生成所有可能的且有效的括号组合,包括暴力求解和回溯方法。
26 0
|
3月前
|
Python
【Leetcode刷题Python】20. 有效的括号
LeetCode上题目“20. 有效的括号”的Python解决方案,使用栈数据结构来验证括号序列的有效性。具体实现中,会在栈中预先放置一个特殊字符以避免在弹出操作时出现空栈错误,并通过匹配左右括号来判断括号序列是否有效。
43 0
|
5月前
|
算法 Java C语言
【经典算法】LeetCode 20:有效的括号(Java/C/Python3实现含注释说明,Easy)
【经典算法】LeetCode 20:有效的括号(Java/C/Python3实现含注释说明,Easy)
45 1